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で公開しているので遊んでみてください。勉強になるゲームです。
でわでわ


 
	
コメント