Unity

【脱出ゲーム制作12】BGM,効果音を鳴らす

オリジナルのボクセルを使って脱出ゲーム制作に挑戦!

用意するもの
  • 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再生には適していません。

とりあえず今回はここまで

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です