目次
オリジナルのボクセルを使って脱出ゲーム制作に挑戦!
用意するもの
- Unity
 - VSCode,VisualStudioなど
 - 3Dモデル
 - 効果音の音声ファイル
 
この記事ではUnity6を使用しています。
効果音を鳴らすシステム
前回は、セーブ機能を実装しました。
今回は効果音を鳴らすようにしたいと思います。
アイテムの取得時・使用時や、ギミックを解いたりしたタイミングで鳴るようにします。
SoundManagerの用意
以下のスクリプトを作成します。
- SEData.cs
 - BGMData.cs
 - SoundDatabase.cs
 - SoundManager.cs
 
SEData.csの作成
SEDataクラスを作成し、SETypeで鳴らしたい効果音をを列挙型で用意します。
SEData.cs
using System;
using UnityEngine;
[Serializable]
public class SEData
{
    public enum SEType
    {
        Open,
        Close,
        Click,
        ItemGet,
        DoorUnlock,
    }
    public SEType type;
    public AudioClip clip;
    public float volume = 1f;
}BGMData.csの作成
BGMも同様に用意します。
SEData.cs
using System;
using UnityEngine;
[Serializable]
public class BGMData
{
    public enum BGMType
    {
        Bgm01,
    }
    public BGMType type;
    public AudioClip clip;
    public float volume = 1f;
}SoundDatabase.csの作成
SoundDatabaseをスクリプタブルオブジェクトで作成します。
SEDatabase.cs
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "SoundDatabase", menuName = "Scriptable Objects/Sound Database")]
public class SoundDatabase : ScriptableObject
{
    public List<SEData> seList;
    public List<BGMData> bgmList;
    public SEData GetSEData(SEData.SEType type)
    {
        return seList.Find(se => se.type == type);
    }
    public BGMData GetBGMData(BGMData.BGMType type)
    {
        return bgmList.Find(bgm => bgm.type == type);
    }
}スクリプタブルオブジェクトを作成
『SoundDatabase』のスクリプタブルオブジェクトを作成します。
Scriptsフォルダで右クリック→Scriptable Object→SoundDatabaseを作成

スクリプタブルオブジェクトの「SeList」を開き、Typeを選択しClipに該当する効果音のファイルを設定しボリュームを設定します。
BGMも同様に設定します。

SoundManager.csの作成
SoundManager.cs
using UnityEngine;
public class SoundManager : MonoBehaviour
{
    [SerializeField] private AudioSource seSource;
    [SerializeField] private AudioSource bgmSource;
    [SerializeField] private SoundDatabase soundDatabase;
    public static SoundManager Instance { get; private set; }
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject); // シーンをまたいでも保持できる
        }
        else
        {
            Destroy(gameObject); // 複製されても自滅
        }
    }
    private void Start()
    {
        PlayBGM(BGMData.BGMType.Bgm01);
    }
    public void PlaySE(SEData.SEType type)
    {
        SEData data = soundDatabase.GetSEData(type);
        if (data != null && data.clip != null)
        {
            seSource.PlayOneShot(data.clip, data.volume);
        }
        else
        {
            Debug.LogWarning($"SE {type} がSoundDatabaseに見つかりませんでした");
        }
    }
    public void PlayBGM(BGMData.BGMType type)
    {
        BGMData data = soundDatabase.GetBGMData(type);
        if (data != null && data.clip != null)
        {
            bgmSource.clip = data.clip;
            bgmSource.volume = data.volume;
            bgmSource.loop = true;
            bgmSource.Play();
        }
        else
        {
            Debug.LogWarning($"BGM {type} がSoundDatabaseに見つかりませんでした");
        }
    }
}Hierarchyに『SoundManager』を作成し、スクリプトをアタッチします。
AudioSourceを二つ追加。

SeSourceとBgmSourceにそれぞれ別々のAudioSoruce設定。

SoundDatabaseも設定します。

これで準備は完了
効果音を鳴らす
効果音を鳴らしたいタイミングで以下のコードを追加します。
SoundManager.Instance.PlaySE(SEData.SEType.Open);実装の流れ
Openメソッドに追加
public void Open()
{
    SoundManager.Instance.PlaySE(SEData.SEType.Open);
}SoundManager「PlaySE」メソッド
public void PlaySE(SEData.SEType type)
{
    SEData data = soundDatabase.GetSEData(type);
    if (data != null && data.clip != null)
    {
        seSource.PlayOneShot(data.clip, data.volume);
    }
    else
    {
        Debug.LogWarning($"SE {type} がSoundDatabaseに見つかりませんでした");
    }
}解説
Openメソッドが呼ばれると、SoundManagerが指定された効果音の種類(今回の場合はOpen)を受け取り、SoundDatabaseから対応する音を探します。そしてその効果音をPlayOneShotで再生します。
BGMを流す
BGMを鳴らしたいタイミングで以下のコードを追加します。
PlayBGM(BGMData.BGMType.Bgm01);実装の流れ
    private void Start()
    {
        PlayBGM(BGMData.BGMType.Bgm01);
    }SoundManager「PlayBGM」メソッド
    public void PlayBGM(BGMData.BGMType type)
    {
        BGMData data = soundDatabase.GetBGMData(type);
        if (data != null && data.clip != null)
        {
            bgmSource.clip = data.clip;
            bgmSource.volume = data.volume;
            bgmSource.loop = true;
            bgmSource.Play();
        }
        else
        {
            Debug.LogWarning($"BGM {type} がSoundDatabaseに見つかりませんでした");
        }
    }解説
PlayBGMメソッドでは、指定されたBGMの種類(BGMType)に対応するデータをSoundDatabaseから取得し、それをAudioSource.clipにセットして再生します。
BGMは長時間ループ再生されることが多いため、PlayOneShotではなく、AudioSource.clipに直接設定してからPlay()を使う必要があります。
PlayOneShotは一時的な効果音向けで、AudioClipを一度だけ再生する仕組みです。PlayOneShotでBGMを再生すると、途中で停止やループ制御ができなかったり、他の音と混ざってしまうため、BGM再生には適していません。
とりあえず今回はここまで

