SoundManager.csのクラス名は何でもよいが、AudioPlayer.csがしっくりくるかもしれない。
参考文献
こちらを自分なりに拡張しました。
https://qiita.com/simanezumi1989/items/681328f30e88737f57b0
C#
↓サウンドマネージャー
GameObjectにつける
SoundManager.cs
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : MonoBehaviour
{
[SerializeField] AudioSource bgmAudioSource;
[SerializeField] AudioSource seAudioSource;
[SerializeField] List<BGMSoundData> bgmSoundDatas;
[SerializeField] List<SESoundData> seSoundDatas;
public float masterVolume = 1;
public float bgmMasterVolume = 1;
public float seMasterVolume = 1;
public static SoundManager Instance { get; private set; }
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(gameObject);
}
}
public void PlayBGM(BGMSoundData.BGM bgm)
{
BGMSoundData data = bgmSoundDatas.Find(data => data.bgm == bgm);
bgmAudioSource.clip = data.audioClip;
bgmAudioSource.volume = data.volume * bgmMasterVolume * masterVolume;
bgmAudioSource.Play();
}
public void StopBGM(BGMSoundData.BGM bgm)
{
BGMSoundData data = bgmSoundDatas.Find(data => data.bgm == bgm);
bgmAudioSource.clip = data.audioClip;
bgmAudioSource.volume = 0;
bgmAudioSource.Stop();
}
public void PlaySE(SESoundData.SE se, Vector3 position)
{
SESoundData data = seSoundDatas.Find(data => data.se == se);
seAudioSource.volume = data.volume * seMasterVolume * masterVolume;
AudioSource.PlayClipAtPoint(data.audioClip, position);
}
}
[System.Serializable]
public class BGMSoundData
{
public enum BGM
{
Title,
Dungeon,
WARNING,// これがラベルになる
}
public BGM bgm;
public AudioClip audioClip;
[Range(0, 1)]
public float volume = 1;
}
[System.Serializable]
public class SESoundData
{
public enum SE
{
Dead,
ItemGet,
Goal,
CAVEAT,// これがラベルになる
}
public SE se;
public AudioClip audioClip;
[Range(0, 1)]
public float volume = 1;
}
↓スタート時にBGMを流す
GameObjectにつける
MusicPlayer.cs
using UnityEngine;
public class MusicPlayer : MonoBehaviour
{
[SerializeField] BGMSoundData.BGM bgm;
void Start()
{
SoundManager.Instance.PlayBGM(bgm);
}
}
↓私がよく使うゲームオーバー時のBGMの切り替え実装方法
プレイヤーのtagのついたオブジェクトにつける
PlayerLife.cs
using UnityEngine;
using UnityEngine.Events;
public class PlayerLife : MonoBehaviour
{
public int playerLife = 100;
public bool isGameOver;
public BGMSoundData.BGM warning;
public static UnityEvent OnGameOver = new UnityEvent();
private void Awake()
{
OnGameOver.RemoveAllListeners();
OnGameOver.AddListener(() =>
{
isGameOver = true;
Debug.Log($"isGameOver: {isGameOver}");
SoundManager.Instance.PlayBGM(warning);
});
}
public void Damage(int damage)
{
if (playerLife <= 0) return;
playerLife -= damage;
if (playerLife <= 0)
{
OnDie();
}
}
void OnDie()
{
OnGameOver.Invoke();
}
}
敵キャラクターコライダーにPlayerのTagがついたオブジェクトが当たりプレイヤーのライフが0になるとBGMが変わる
敵のオブジェクトにつける
Enemy.cs
using UnityEngine;
public class Enemy : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
GameObject gameObj = collision.gameObject;
if(collision.gameObject.tag == "Player")
{
PlayerLife playerLife = gameObj.GetComponent<PlayerLife>();
playerLife.Damage(10);
Debug.Log($"playerのライフ: {playerLife.playerLife}");
}
}
}
おまけ
↓こうするとゲームオーバーになったときプレイヤーの操作入力を受け付けなくすることができる
PlayerMove.cs
void Update(){
PlayerLife.OnGameOver.AddListener(() =>
{
return;
});
// プレイヤーの移動処理
/*
省略
*/
}