Unity初心者によるクイズゲーム制作、最終回です。
今回はBGMとSEを鳴らします。そして、これらの音量設定画面を作ります。
- Mac mini (M1, 2020)
- Unity 2022.3.36f1
BGMを鳴らす
クイズゲームにBGMは必要かというのは賛否が分かれるところですが、私は必要派です。ゲームが華やぐからね。
まず、 BGMの音声ファイルを用意します。優雅なクラシック音楽にしたかったので、classixさんからお借りしました。クイズ画面用と結果画面用の2種類を用意します。
Assetsフォルダの下にSoundsフォルダを作成して、そこに音声ファイルをインポートします。
ヒエラルキータブで右クリック「Audio > Audio Source」を選択してオブジェクトを作成します。名前をBGMに変更します。
これがBGMを司るオブジェクトとなります。
BGMオブジェクトのインスペクターで「Audio Source > Loop」にチェックを入れます。これでBGMがループ再生されるようになります。
Assets/Scriptsフォルダの下にC#スクリプトを作成します。名前をBGMController.csにします。
BGMController.csをBGMオブジェクトにアタッチします。
BGMController.csの内容を次のようにします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening; // DOTweenを使う場合に追加
public class BGMController : MonoBehaviour
{
[SerializeField] private AudioClip mainBGM; // メインBGMの音源データ
[SerializeField] private AudioClip resultBGM; // 結果BGMの音源データ
private AudioSource audioSource; // Audio Source
private void Start()
{
audioSource = GetComponent<AudioSource>(); // AudioSourceコンポーネントを取得
}
// メインBGM再生
public void PlayMainBGM()
{
audioSource.clip = mainBGM;
audioSource.Play();
}
// メインBGMをフェードアウトして結果BGM再生
public void SwitchToResultBGM()
{
audioSource
.DOFade(0, 1f)
.OnComplete(() =>
{
audioSource.Stop();
audioSource.volume = 1f;
audioSource.clip = resultBGM;
audioSource.Play();
});
}
// 結果BGMフェードアウト
public void FadeOutResultBGM()
{
audioSource
.DOFade(0, 2f)
.OnComplete(() =>
{
audioSource.Stop();
audioSource.volume = 1f;
});
}
}
BGMを止めるときにaudioSource.Stop()
とすると突然BGMが止まってしまうので、フェードアウトするようにしました。フェードアウトはDOTweenの.DOFade()
を使っています。第1引数が最終的な音量、第2引数がフェードアウトの時間(秒)です。
TitleController.csを修正します。
public class TitleController : MonoBehaviour
{
// ...省略...
public BGMController bgmController; // BGMController
// スタートボタン
public void StartGame()
{
// ...省略...
bgmController.PlayMainBGM(); // メインBGMを再生
}
// ...省略...
}
これで「スタート」ボタンを押したらメインBGMが流れるようになります。
QuizController.csを修正します。
public class QuizController : MonoBehaviour
{
// ...省略...
public BGMController bgmController; // BGMController
// ...省略...
// 終了ボタン
public void FinishGame()
{
// ...省略...
bgmController.SwitchToResultBGM(); // メインBGMをフェードアウトして結果BGMを再生
}
// ...省略...
}
「終了」ボタンを押したらメインBGMをフェードアウトして結果BGMが再生されます。
ResultController.csを修正します。
public class ResultController : MonoBehaviour
{
// ...省略...
public BGMController bgmController; // BGMController
public void BackToTitle()
{
// ...省略...
bgmController.FadeOutResultBGM(); // 結果BGMをフェードアウト
}
// ...省略...
}
「タイトルへ」ボタンを押したら結果BGMがフェードアウトします。
以上でBGMを鳴らすための作業は完了です。
SEを鳴らす
正解時のピンポン、不正解時のブーを鳴らすことで、とってもクイズゲームらしくなります。
正解音、不正解音、クリック音の音声ファイルを用意します。いつもの効果音ラボさんからお借りしました。
これらをAssets/Soundsフォルダにインポートします。
ヒエラルキータブで右クリック「Audio > Audio Source」を選択してオブジェクトを作成します。名前をSEに変更します。
そう、これがSEを司るオブジェクトです。BGMと分けるのは、個別に音量設定できるようにするためです。
Assets/Scripts下にSEController.csという名前のC#スクリプトを作成します。
SEController.csをSEオブジェクトにアタッチします。
SEController.csは次のとおりです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SEController : MonoBehaviour
{
[SerializeField] private AudioClip clickSE; // クリックSEの音声データ
[SerializeField] private AudioClip correctSE; // 正解SEの音声源データ
[SerializeField] private AudioClip incorrectSE; // 不正解SEの音声データ
private AudioSource audioSource; // Audio Source
private void Start()
{
audioSource = GetComponent<AudioSource>(); // AudioSourceコンポーネントを取得
}
// クリックSE再生
public void PlayClickSE()
{
audioSource.PlayOneShot(clickSE);
}
// 正解SE再生
public void PlayCorrectSE()
{
audioSource.PlayOneShot(correctSE);
}
// 不正解SE再生
public void PlayIncorrectSE()
{
audioSource.PlayOneShot(incorrectSE);
}
}
それぞれのSEを鳴らすための関数を定義しました。
ボタンのクリック音
各ボタンをクリックしたときにクリック音のSEを鳴らす設定をします。
ボタンのインスペクターの「Button > On Click ()」を次のように設定します。
ちなみに、このゲームのボタンは全部で12個あります。それぞれに上記の設定をします。
- タイトル画面
- スタート
- 成績
- 設定
- クイズ画面
- 選択肢(4つ)
- 終了
- 次へ
- 結果画面
- タイトルへ
- 成績画面
- 閉じる
- 設定画面
- 閉じる
正解・不正解のSE
QuizController.csに以下のコードを追加します。
public class QuizController : MonoBehaviour
{
// ...省略...
public SEController seController; // SEController
// ...省略...
// 答え合わせを遅らせるコルーチン
IEnumerator DelayAnswer(int selectedIndex)
{
yield return new WaitForSeconds(1f);
if (isAnswerSelected)
{
// 答え合わせ処理
if (selectedIndex == correctAnswerIndex) // 正解だったら
{
// ...省略...
seController.PlayCorrectSE(); // 正解SEを再生
}
else // 不正解だったら
{
// ...省略...
seController.PlayIncorrectSE(); // 不正解SEを再生
}
// ...省略...
}
}
}
設定画面の作成
BGMとSEの音量を設定する仕組みを作ります。
SettingsController.csを以下のように修正します。
public class SettingsController : MonoBehaviour
{
// ...省略...
public Slider bgmSlider; // BGMのスライダー
public Slider seSlider; // SEのスライダー
public AudioSource bgmAudioSource; // BGMのAudioSource
public AudioSource seAudioSource; // SEのAudioSource
public static float bgmVolume; // BGMの音量
void Start()
{
bgmSlider.value = PlayerPrefs.GetFloat("BGMVolume", 0.2f); // 保存されたBGM音量を読み込む
seSlider.value = PlayerPrefs.GetFloat("SEVolume", 1f); // 保存されたSE音量を読み込む
UpdateVolume();
}
public void CloseSettings()
{
// 音量設定の保存
PlayerPrefs.SetFloat("BGMVolume", bgmSlider.value);
PlayerPrefs.SetFloat("SEVolume", seSlider.value);
// ...省略...
}
public void UpdateVolume()
{
bgmAudioSource.volume = bgmSlider.value; // BGM音量を設定
seAudioSource.volume = seSlider.value; // SE音量を設定
bgmVolume = bgmSlider.value; // BGM音量を変数に代入
}
}
そして、BGMSliderとSESliderのインスペクターで「Slider > On Value Changed (Single)」を以下のように設定します。これで、スライダーの値が変更されたときにUpdateVolume()
関数が実行されるようになります。
BGMController.csを修正します。
public class BGMController : MonoBehaviour
{
// ...省略...
public SettingsController settingsController; // Settings Controller
// ...省略...
// メインBGMをフェードアウトして結果BGM再生
public void SwitchToResultBGM()
{
audioSource
.DOFade(0, 1f)
.OnComplete(() =>
{
audioSource.Stop();
// audioSource.volume = 1f; 以下に修正
audioSource.volume = SettingsController.bgmVolume;
audioSource.clip = resultBGM;
audioSource.Play();
});
}
// 結果BGMフェードアウト
public void FadeOutResultBGM()
{
audioSource
.DOFade(0, 2f)
.OnComplete(() =>
{
audioSource.Stop();
// audioSource.volume = 1f; 以下に修正
audioSource.volume = SettingsController.bgmVolume;
});
}
}
BGMをフェードアウトした後に音量をもとに戻す処理のところです。1f
(最大音量)に戻していたのをbgmVolume
(設定音量)に戻すように修正します。
さいごに
クイズゲームが完成しました。いえい。unityroomで公開しているので遊んでみてください。勉強になるゲームです。
でわでわ
コメント