パープルハット

※当サイトではGoogleアドセンス広告を利用しています

Unity BGMとSE管理用クラスの作成





目的

  • SEを重ねて鳴らすにはAudioSourceをSEの数だけ用意しなければならないけどいちいち準備するのは面倒
  • BGMの操作をいちいちaudioSource変数を介してするのは面倒

などがあったので、BGMとSEをまとめて管理するクラスを作成しました。




作成したクラス

概要

  • BGMに関してはAudioSourceをはじめから用意しておき、それをスクリプトで使用するようにしました(重ねて鳴らすのはこのクラスでは不可)。
  • SE用のAudioSourceはSEを鳴らす処理を呼び出したときに割り当てる。すべてのAudioSourceが使用中の場合は新たに生成する(重ねて鳴らせる)。
  • ポーズ画面なども想定してSEはまとめて一時停止できるようにした。


各関数の役割は次の表のとおり。AudioSourceの関数などを利用していますが、分からなかったらこちらの記事を参考にしてください(Unity 音楽の再生(再生・停止、5秒移動、再生速度の変化など) - ミドリ黄のプログラミングメモノート)。

PlayBGM(AudioClip) 引数に音源を設定し、BGMを鳴らす。
PauseBGM() BGMを一時停止する
UnPauseBGM() ↑で一時停止したBGMを再開する。
PlaySE(AudioClip clip) 引数に音源を設定し、SEを鳴らす。SEを鳴らしているAudioSourceが返り値となっているため、SEごとに操作をしたい場合はこれを使う。
PauseAllSE() すべてのSEを止める。ポーズ画面などに使用。
UnPauseAllSE() すべてのSEを再開。ポーズ画面から戦闘に戻った時などに使用。



ソースコード

using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class AudioPlayer : MonoBehaviour
{
    //BGM用のオーディオソース
    [SerializeField] protected AudioSource bgmAudioSource;

    //SE用のオーディオソース
    List<AudioSource> seAudioSources = new List<AudioSource>();

    //シングルトンにすることでアクセスを容易にしている
    public static AudioPlayer I { get; private set; }


    private void Awake()
    {
        I = this;
    }

    //BGMを最初から鳴らす
    public void PlayBGM(AudioClip clip)
    {
        bgmAudioSource.clip = clip;
        bgmAudioSource.Play();
    }

    //BGMを一時停止
    public void PauseBGM()
    {
        bgmAudioSource.Pause();
    }

    //BGMを再開する
    public void UnPauseBGM()
    {
        bgmAudioSource.UnPause();
    }


    //SEを鳴らす
    public AudioSource PlaySE(AudioClip clip)
    {
        //鳴らしていないAudioを順に探す
        var a = seAudioSources.FirstOrDefault(s => !s.isPlaying);

        //無かったら新しく追加する
        if (a == null)
        {
            //新たなゲームオブジェクトを作成して、子オブジェクトとして追加する
            GameObject obj = new GameObject("");
            obj.transform.SetParent(transform);


            //生成したobjにAudioSourceを追加して、リストに追加
            a = obj.AddComponent<AudioSource>();
            seAudioSources.Add(a);
        }

        //clipを設定
        a.clip = clip;

        //鳴らす
        a.Play();

        return a;
    }

    //すべてのSEを一時停止
    public void PauseAllSE()
    {
        foreach (var s in seAudioSources)
        {
            s.Pause();
        }
    }

    //すべてのSEを再開する
    public void UnPauseAllSE()
    {
        foreach (var s in seAudioSources)
        {
            s.UnPause();
        }
    }
}





使用例

オブジェクトの準備

「Create Empty」で空のオブジェクトを用意したら先ほどのスクリプトとAudioSourceをアタッチします。



操作用スクリプトの用意

次に操作用のスクリプトを用意したので、これを適当なゲームオブジェクトにアタッチします。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
    //音源
    [SerializeField] AudioClip bgm1;//BGM1
    [SerializeField] AudioClip bgm2;//BGM2
    [SerializeField] AudioClip se1;//SE1
    [SerializeField] AudioClip se2;//SE1

    AudioSource as1;
    AudioSource as2;

    void Update()
    {
        //SEについての処理

        //Qを押すとSE1を最初から鳴らす
        if (Input.GetKeyDown(KeyCode.Q))
        {
            as1 = AudioPlayer.I.PlaySE(se1);
        }

        //Wを押すとSE1を停止
        else if (Input.GetKeyDown(KeyCode.W))
        {
            as1?.Stop();
        }

        //Eを押すとSE2を最初から鳴らす
        else if (Input.GetKeyDown(KeyCode.E))
        {
            as2 = AudioPlayer.I.PlaySE(se2);
        }

        //Rを押すとSE2を停止
        else if (Input.GetKeyDown(KeyCode.R))
        {
            as2?.Stop();
        }

        //Tを押すとすべてのSEを一時停止
        else if (Input.GetKeyDown(KeyCode.T))
        {
            AudioPlayer.I.PauseAllSE();
        }

        //Yを押すとすべてのSEを再開
        else if (Input.GetKeyDown(KeyCode.Y))
        {
            AudioPlayer.I.UnPauseAllSE();
        }




        //ここからBGMについての処理

        //Aを押すとBGM1を鳴らす
        else if (Input.GetKeyDown(KeyCode.A))
        {
            AudioPlayer.I.PlayBGM(bgm1);
        }

        //Sを押すとBGM2を鳴らす
        else if (Input.GetKeyDown(KeyCode.S))
        {
            AudioPlayer.I.PlayBGM(bgm2);
        }

        //Dを押すとBGMを一時停止
        else if (Input.GetKeyDown(KeyCode.D))
        {
            AudioPlayer.I.PauseBGM();
        }

        //Fを押すとBGMを再開
        else if (Input.GetKeyDown(KeyCode.F))
        {
            AudioPlayer.I.UnPauseBGM();
        }
    }
}



操作用スクリプトの設定

先ほどのスクリプトをアタッチしたら4つのAudioClipを設定します。
また、先ほどのスクリプトによりキーボードから以下の操作ができます。

ボタン 処理
Q SE1を最初から鳴らす
W SE1を停止
E SE2を最初から鳴らす
R SE2を停止
T すべてのSEを一時停止
Y すべてのSEを再開
A BGM1を鳴らす
S BGM2を鳴らす
D BGMを一時停止
F BGMを再開