はじめに
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 Changed にSetBGMVolume()を設定すると、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の役割が理解しやすくなりました。


コメント