BGM・SEを管理する専用のクラス、SoundManagerを作成します。どこのクラスから使用されてもいいようにシングルトンにします。
public class SoundManager { private readonly AudioSource bgmAudioSource; private readonly AudioSource seAudioSource; private readonly AudioClip[] allAudioPool; private readonly Dictionary<string, AudioClip> bgmPool = new Dictionary<string, AudioClip>(); private readonly Dictionary<string, AudioClip> sePool = new Dictionary<string, AudioClip>(); public static SoundManager Instance { get; } = new SoundManager(); //BGMのAudioclipをDictionaryに追加。 public void LoadBGM(string key, string name) { if (bgmPool.ContainsKey(key)) return; var audio = GetAudioClip(name); bgmPool.Add(key, audio); } //SEのAudioclipをDictionaryに追加。 public void LoadSE(string key, string name) { if (sePool.ContainsKey(key)) return; var audio = GetAudioClip(name); sePool.Add(key, audio); } //BGMの再生。 public void PlayBGM(string name, float volume = 1) { if (bgmPool[name] == null) throw new Exception("not found"); bgmAudioSource.clip = bgmPool[name]; bgmAudioSource.loop = true; bgmAudioSource.volume = Mathf.Clamp01(volume); bgmAudioSource.Play(); } //SEの再生。 public void PlaySE(string name, float volume = 1) { if (sePool[name] == null) throw new Exception("not found"); volume = Mathf.Clamp01(volume); seAudioSource.PlayOneShot(sePool[name], volume); } //BGMの停止。 public void StopBGM() { bgmAudioSource.Stop(); } //BGMの一時停止。 public void PauseBGM() { if (bgmAudioSource.isPlaying) bgmAudioSource.Pause(); else bgmAudioSource.UnPause(); } //SEの停止。 public void StopSE() { seAudioSource.Stop(); } private SoundManager() { allAudioPool = Resources.LoadAll<AudioClip>("Audio"); var obj = new GameObject("SoundManager"); bgmAudioSource = obj.AddComponent<AudioSource>(); seAudioSource = obj.AddComponent<AudioSource>(); UnityEngine.Object.DontDestroyOnLoad(obj); } //DictionaryからAudioClipを取得。 private AudioClip GetAudioClip(string name) { var audio = allAudioPool.FirstOrDefault(a => a.name == name); if (audio == null) throw new Exception("not found"); return audio; } }
GameManagerの起動時にAudioClipを読み込みます。
public class GameManager : MonoBehaviour { private SoundManager soundManager; private void Awake() { SetAudio(); } private void SetAudio() { soundManager = SoundManager.Instance; //パックマンがエサを食べたとき。 soundManager.LoadSE("EatDot", "Byu"); //パックマンがパワーエサを食べたとき。 soundManager.LoadSE("EatPowerCokie", "ByChance"); //パックマンがゴーストを食べたとき。 soundManager.LoadSE("EatGhost", "Byuu"); //パックマンが死んだとき。 soundManager.LoadSE("Dead", "Qyurururu"); //ゴーストが通常状態のとき。 soundManager.LoadBGM("GhostNormal", "Panic"); //ゴーストが恐慌状態のとき。 soundManager.LoadBGM("GhostScare", "LFO"); //ゴーストが死亡状態のとき。 soundManager.LoadSE("GhostDead", "Obake"); } }
再生したい部分でPlayBGM、PlaySEを実行します。
[SerializeField] private Text readyText = default; private List<AGhost> ghosts; private Pacman pacman; private SoundManager soundManager; private bool isScare; private float scareEndTime; //一度の恐慌状態で食べたゴーストの数。 private int eatenGhost; private void FixedUpdate() { if (isScare && scareEndTime < Time.fixedTime ) { isScare = false; eatenGhost = 0; ghosts.ForEach(g => g.Calm()); //BGMを再生。 soundManager.StopBGM(); soundManager.PlayBGM("GhostNormal", 0.6f); } } //Readyを一定時間表示した後、パックマン、ゴーストをActiveにするコルーチン。 private IEnumerator CoroutineStart(Action callback) { readyText.gameObject.SetActive(true); callback(); yield return new WaitForSeconds(readySpan); readyText.gameObject.SetActive(false); pacman.Run(); ghosts.ForEach(g => g.Run()); //BGMを再生。 soundManager.PlayBGM("GhostNormal", 0.6f); }
public class Dead : IState { private readonly Mover mover; private readonly Animator animator; private readonly SoundManager soundManager; public void SetState() { mover.SetWaypoints(nestWaypoints); mover.Speed = defaultSpeed * 2f; animator.SetBool("IsScare", false); animator.SetBool("IsCalmSoon", false); animator.SetBool("IsDead", true); //BGMを再生。 soundManager.PlaySE("GhostDead", 0.2f); } }