1
2

Unityで汎用性の高いSoundManagerの作成

Last updated at Posted at 2024-03-25

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;
    });

    // プレイヤーの移動処理
    /*
    省略
    */
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2