UnityでBGM・SEの音量設定を作る|SliderとPlayerPrefsで設定を保存

Unity

はじめに

Unityで制作しているクイズゲームに、オプション画面を追加しました。

今回実装したのは、

  • 設定画面の表示・非表示
  • SliderによるBGM音量変更
  • SliderによるSE音量変更
  • PlayerPrefsによる音量設定の保存
  • ゲームを再起動したときの音量設定の読み込み

です。

最初は、

bgmAudioSource.volume = volume;

で音量を変更できれば設定は終わりだと思っていました。

しかし、この方法ではUnityの再生を終了すると音量が元に戻ってしまいます。

そこで今回は、PlayerPrefs を使って設定を保存しました。

オプション画面を作る

まずタイトル画面に設定ボタンを配置しました。

Hierarchyは次のような構成です。

Canvas
├ GameStartButton
├ OptionButton
└ OptionPanel
├ SettingText
├ BGMText
├ BGMSlider
├ SEText
├ SESlider
└ CloseButton

OptionPanel はゲーム開始時には非表示にします。

void Start()
{
optionPanel.SetActive(false);
}

設定ボタンを押したときに表示します。

public void OnOptionButton()
{
optionPanel.SetActive(true);
}

Closeボタンでは再び非表示にします。

public void OnCloseButton()
{
optionPanel.SetActive(false);
}

これで、

設定ボタン

OptionPanel表示

Close

OptionPanel非表示

という基本的な設定画面ができました。

SliderでBGM音量を変更する

AudioManagerではBGM用とSE用のAudioSourceを分けています。

[SerializeField] private AudioSource bgmAudioSource;
[SerializeField] private AudioSource seAudioSource;

BGM音量を変更する関数を作ります。

public void SetBGMVolume(float volume)
{
bgmAudioSource.volume = volume;
}

SliderのValueを 0~1 に設定しておけば、その値をそのままAudioSource.volumeに使用できます。

Slider = 0

volume = 0

無音

Slider = 0.5

volume = 0.5

Slider = 1

volume = 1

Sliderの On Value ChangedSetBGMVolume()を設定すると、Sliderを動かすたびに現在の値がvolumeに渡されます。

On Value Changedとは?

Sliderで音量を変更するときに使用したのが、Sliderコンポーネントにある On Value Changed です。

最初は「なぜSliderを動かすだけで SetBGMVolume() が呼ばれるのか」がよく分かっていませんでした。

On Value Changed は簡単にいうと、

SliderのValueが変更されたときに、登録した処理を実行するイベント

Buttonの On Click と比較すると分かりやすいです。

Button

On Click

ボタンが押されたら処理を実行

Slider

On Value Changed

Sliderの値が変わったら処理を実行

Sliderの値をSetBGMVolume(関数)に渡す

AudioManagerには、BGM音量を変更するために次の関数を用意しました。

public void SetBGMVolume(float volume)
{
bgmAudioSource.volume = volume;
PlayerPrefs.SetFloat(“BGMVolume”, volume);
}

ここで重要なのが、float volume という引数です。

Sliderの On Value Changed から現在のValueを、この volume に渡すことができます。

例えばSliderを動かしてValueが 0.3 になった場合、

Slider
Value = 0.3

On Value Changed

SetBGMVolume(0.3)

volume = 0.3

という流れになります。

そのため、

bgmAudioSource.volume = volume;

このとき実質、

bgmAudioSource.volume = 0.3f;

と同じことになります。

結果として、Sliderを動かした位置に合わせてBGM音量も変化します。

Dynamic floatを選択する

SliderのInspectorにある On Value Changed (Single)SetBGMVolume() を登録するときは、Sliderの現在値を渡すために Dynamic float の方を選択します。

これによって、自分で 0.5 などの固定値を指定するのではなく、SliderのValueが自動的に引数へ渡されます。

「Sliderの値が変わったので、この値を使って登録した関数を実行してください」と橋渡ししているのが On Value Changed です。

SEも同じように変更する

SEも基本的な仕組みは同じです。

public void SetSEVolume(float volume)
{
seAudioSource.volume = volume;
}

BGMとSEでAudioSourceを分けているため、それぞれ別々に音量を調整できます。

問題:Unityを停止すると音量が元に戻る

ここまでで音量は変更できました。

しかし、Unityの再生を停止して再び実行すると、設定した音量が元に戻ってしまいました。

理由は、

bgmAudioSource.volume = volume;

現在のAudioSourceの音量を変更しているだけだからです。

これは設定を保存しているわけではありません。

そこでPlayerPrefsを使用します。

PlayerPrefsでBGM音量を保存する

BGM音量変更時に、次の1行を追加します。

public void SetBGMVolume(float volume)
{
 bgmAudioSource.volume = volume;

 PlayerPrefs.SetFloat(“BGMVolume”, volume);

重要なのが、

PlayerPrefs.SetFloat(“BGMVolume”, volume);

これは、

"BGMVolume"という名前でvolumeの値を保存する

という意味です。

例えばSliderを0.3にした場合、

volume = 0.3

// 現在のBGM音量を変更
bgmAudioSource.volume = 0.3

// 0.3を保存
BGMVolume → 0.3

ここで、

bgmAudioSource.volume = volume;

PlayerPrefs.SetFloat(“BGMVolume”, volume);

は役割が違います。

前者は音量変更、後者は値の保存です。

保存したBGM音量を読み込む

保存しただけでは、AudioSourceには戻りません。

ゲーム開始時に保存した値を取得します。

float bgmVolume =
PlayerPrefs.GetFloat(“BGMVolume”, 1.0f);

bgmAudioSource.volume = bgmVolume;

GetFloat()は、

PlayerPrefs.GetFloat(“BGMVolume”, 1.0f);

と書いた場合、

"BGMVolume"という名前で保存されている値を取得する。
保存されていなければ1.0fを返す。

という意味です。

例えば前回、

BGMVolume → 0.3

と保存していれば、

PlayerPrefs.GetFloat(“BGMVolume”, 1.0f);

から返ってくるのは0.3です。

一方、初回起動でまだ何も保存されていなければ1.0が返ってきます。

SetFloatとGetFloatの違い

今回、一番混乱したのがここでした。

整理すると非常にシンプルです。

処理役割
AudioSource.volume現在の音量を変更
PlayerPrefs.SetFloat()数値を保存
PlayerPrefs.GetFloat()保存した数値を取得

例えば、

PlayerPrefs.SetFloat(“BGMVolume”, 0.3f);

で保存して、

float bgmVolume =
PlayerPrefs.GetFloat(“BGMVolume”, 1.0f);

で取り出します。

SE音量も保存する

SEについても同じです。

public void SetSEVolume(float volume)
{
seAudioSource.volume = volume;
PlayerPrefs.SetFloat(“SEVolume”, volume);
}

読み込みは、

float seVolume =PlayerPrefs.GetFloat(“SEVolume”, 1.0f);
seAudioSource.volume = seVolume;

"BGMVolume""SEVolume"という異なる名前を使うことで、それぞれ別の値として保存できます。

まとめ

今回の実装で特に重要だったのは、「音量を変更すること」と「音量を保存すること」は別の処理だという点です。

bgmAudioSource.volume = volume;

は現在の音量変更。

PlayerPrefs.SetFloat(“BGMVolume”, volume);

は保存。

PlayerPrefs.GetFloat(“BGMVolume”, 1.0f);

は保存した値の取得です。

この3つを分けて考えることで、PlayerPrefsの役割が理解しやすくなりました。

コメント