Last active
June 8, 2022 08:02
-
-
Save Islington036/c0e25f522e8eb41954438992e15fb71d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Audio; | |
[System.Serializable] | |
public class AudioData | |
{ | |
// 名前(インスペクターからの登録) | |
public string name = ""; | |
// AudioClip | |
public AudioClip Clip = null; | |
// Audioの音量設定用変数 | |
public float SoundVolume = 1; | |
} | |
public class SoundManager : SingletonMonoBehaviour<SoundManager> | |
{ | |
//============================================================================= | |
// 変数 | |
//============================================================================= | |
// ボリューム関連 | |
[SerializeField, Range(0, 1), Tooltip("マスタ音量")] | |
private float volume = 1; | |
[SerializeField, Range(0, 1), Tooltip("BGMの音量")] | |
private float BGM_Total_Volume = 0.1f; | |
[SerializeField, Range(0, 1), Tooltip("SEの音量")] | |
private float SE_Total_Volume = 0.2f; | |
[SerializeField, Tooltip("BGMの同時再生可能数")] | |
private int BGM_PlaybackNum = 5; | |
[SerializeField, Tooltip("SEの同時再生可能数")] | |
private int SE_PlaybackNum = 5; | |
// ミュート中 | |
[SerializeField] | |
private bool Mute = false; | |
// AudioSource | |
private AudioSource[] BGM_Sources; | |
private AudioSource[] SE_Sources; | |
// オーディオ情報 | |
[SerializeField] | |
List<AudioData> BGMData; | |
[SerializeField] | |
List<AudioData> SEData; | |
//============================================================================= | |
// 起動時 | |
//============================================================================= | |
protected override void Awake() | |
{ | |
// 継承元を呼び出し | |
base.Awake(); | |
// 同時再生可能数を元にAudioSourceを初期化 | |
BGM_Sources = new AudioSource[BGM_PlaybackNum]; | |
SE_Sources = new AudioSource[SE_PlaybackNum]; | |
// BGM用にAudioSourceコンポーネントを取得 | |
for (int i = 0; i < BGM_Sources.Length; i++) | |
{ | |
// AudioSourceを追加 | |
BGM_Sources[i] = gameObject.AddComponent<AudioSource>(); | |
// 初期ボリュームをセット | |
BGM_Sources[i].volume = BGM_Total_Volume * volume; | |
} | |
// SE用にAudioSourceコンポーネントを取得 | |
for (int i = 0; i < SE_Sources.Length; i++) | |
{ | |
// AudioSourceを追加 | |
SE_Sources[i] = gameObject.AddComponent<AudioSource>(); | |
// 初期ボリュームをセット | |
SE_Sources[i].volume = SE_Total_Volume * volume; | |
} | |
// 呼び出し用変数に名前を入力 | |
if (BGMData == null || SEData == null) | |
{ | |
Debug.LogError(BGMData + "か" + SEData + " が空です"); | |
} | |
} | |
//============================================================================= | |
// 音量変更系統 | |
//============================================================================= | |
/// <summary> | |
/// BGMボリューム変更 | |
/// </summary> | |
public float BGM_TotalVolume | |
{ | |
set | |
{ | |
BGM_Total_Volume = Mathf.Clamp01(value); | |
// 全てのBGMのAudioSourceに設定 | |
for (int i = 0; i < BGM_Sources.Length; i++) | |
{ | |
BGM_Sources[i].volume = BGM_Total_Volume * volume; | |
} | |
} | |
get{ return BGM_Total_Volume; } | |
} | |
/// <summary> | |
/// SEボリューム変更 | |
/// </summary> | |
public float SE_TotalVolume | |
{ | |
set | |
{ | |
SE_Total_Volume = Mathf.Clamp01(value); | |
// 全てのSEのAudioSourceに設定 | |
for (int i = 0; i < SE_Sources.Length; i++) | |
{ | |
SE_Sources[i].volume = SE_Total_Volume * volume; | |
} | |
} | |
get{ return SE_Total_Volume; } | |
} | |
/// <summary> | |
/// ミュート選択 | |
/// </summary> | |
public bool IsMute | |
{ | |
set | |
{ | |
Mute = value; | |
if(value) | |
{ | |
StopBGMAll(); | |
StopSEAll(); | |
} | |
} | |
get { return Mute; } | |
} | |
//============================================================================= | |
// 名前の一致を検索 | |
//============================================================================= | |
/// <summary> 曲名もしくはファイル名と一致するか判定</summary> | |
/// <param name="Data"> オーディオデータ </param> | |
/// <param name="name"> 判定する名前 </param> | |
/// <returns> 曲名もしくはタイトル名と一致したらtrueを返す </returns> | |
private bool FindTitleMatch(AudioData Data, string name) | |
{ | |
if(Data.name.Equals(name) || Data.Clip.name.Equals(name)) { return true; } | |
return false; | |
} | |
//============================================================================= | |
// ファイル名もしくは名前からAudioClipを検索 | |
//============================================================================= | |
/// <summary> ファイル名もしくは名前からAudioClipを検索 </summary> | |
/// <param name="Data"> オーディオデータ配列 </param> | |
/// <param name="name"> 判定する名前 </param> | |
/// <returns> 見つからなかった場合はnullを返す </returns> | |
private AudioClip FindAudioClip(AudioData[] Data, string name) | |
{ | |
foreach(AudioData Audio in Data) | |
{ | |
if(FindTitleMatch(Audio, name)){ return Audio.Clip; } | |
} | |
return null; | |
} | |
//============================================================================= | |
// タイトルから配列の番号を検索 | |
//============================================================================= | |
/// <summary> | |
/// 曲の名前から配列の格納番号を検索 | |
/// </summary> | |
/// <param name="name">曲の名前</param> | |
/// <param name="isBGM">BGMかSEかの指定</param> | |
private int GetIndex(string name, bool isBGM) | |
{ | |
if (isBGM) | |
{ | |
for (int i = 0; i < BGMData.Count; i++) | |
{ | |
if (FindTitleMatch(BGMData[i], name)) | |
{ | |
return i; | |
} | |
} | |
} | |
else | |
{ | |
for (int i = 0; i < SEData.Count; i++) | |
{ | |
if (FindTitleMatch(SEData[i], name)) | |
{ | |
return i; | |
} | |
} | |
} | |
Debug.LogError("指定された名前のファイルは登録されていません"); | |
return -1; | |
} | |
//============================================================================= | |
// 再生中ではない空いているAudioSourceを検索 | |
//============================================================================= | |
/// <summary> 空いているAudioSourceを検索 </summary> | |
/// <param name="Source"> 検索するAudioSource配列 </param> | |
/// <returns> 再生可能な番号を返す </returns> | |
private int PlayingNumberSearch(AudioSource[] Source) | |
{ | |
// 再生するBGM_Sourcesの番号 | |
int AudioSourceIndex = -1; | |
// 再生終了しているAudioSourceを見つける | |
for (int i = 0; i < Source.Length; i++) | |
{ | |
// 再生していないAudioSourceを検索 | |
if (Source[i].time == 0.0f && !Source[i].isPlaying) | |
{ | |
// 再生するAudioSourceを空にする | |
Source[i].clip = null; | |
// 再生する番号を決定 | |
AudioSourceIndex = i; | |
} | |
} | |
// 空いている番号が見つからなかった場合 | |
if (AudioSourceIndex == -1) | |
{ | |
// 先頭のBGM_Sourcesを更新 | |
AudioSourceIndex = 0; | |
} | |
// 再生可能な番号を返す | |
return AudioSourceIndex; | |
} | |
//============================================================================= | |
// 音量をセット | |
//============================================================================= | |
/// <summary> BGMの音量をセット </summary> | |
/// <param name="name"> ファイル名 </param> | |
/// <param name="SoundVolume"> 設定する音量 </param> | |
/// <returns> 設定が反映されたらtrue </returns> | |
public bool BGM_SoundVolumeSet(string name, float SoundVolume) | |
{ | |
for (int i = 0; i < BGMData.Count; i++) | |
{ | |
if(FindTitleMatch(BGMData[i], name)) | |
{ | |
BGMData[i].SoundVolume = SoundVolume; | |
return true; | |
} | |
} | |
return false; | |
} | |
/// <summary> SEの音量をセット </summary> | |
/// <param name="name"> ファイル名 </param> | |
/// <param name="SoundVolume"> 設定する音量 </param> | |
/// <returns> 設定が反映されたらtrue </returns> | |
public bool SE_SoundVolumeSet(string name, float SoundVolume) | |
{ | |
for (int i = 0; i < SEData.Count; i++) | |
{ | |
if (FindTitleMatch(SEData[i], name)) | |
{ | |
SEData[i].SoundVolume = SoundVolume; | |
return true; | |
} | |
} | |
return false; | |
} | |
//============================================================================= | |
// 名前から再生中のAudioSourceを検索を検索 | |
//============================================================================= | |
/// <summary> 名前から再生中のAudioSourceを検索を検索 </summary> | |
/// <param name="Source"> 検索するAudioSource配列 </param> | |
/// <param name="name"> 曲名 </param> | |
/// <returns> 曲が再生されている場合は番号、されていない場合は-1を返す </returns> | |
private int AudioSourceNameToNumber(AudioData[] Data, AudioSource[] Source, string name) | |
{ | |
// AudioSourceを検索 | |
for (int i = 0; i < Source.Length; i++) | |
{ | |
// nullの場合は以下の処理を行わない | |
if(Source[i].clip == null) { continue; } | |
// オーディオデータを検索 | |
foreach (AudioData Audio in Data) | |
{ | |
// ファイル名もしくは名前から一致するAudioClipを検索 | |
if(FindTitleMatch(Audio, name)) | |
{ | |
// 曲名と一致するものが合った場合 | |
if (Source[i].clip.name.Equals(Audio.Clip.name)) | |
{ | |
// 格納されている配列の番号を返す | |
return i; | |
} | |
} | |
} | |
} | |
// 見つからなかった場合は-1を返す | |
return -1; | |
} | |
//============================================================================= | |
// BGM系統 | |
//============================================================================= | |
/// <summary> | |
/// BGM再生 | |
/// </summary> | |
/// <param name="bgmType">BGMのタイトル</param> | |
/// <param name="loop">ループの有無</param> | |
/// <param name="PlayVolume">再生時のボリューム</param> | |
public void PlayBGM(string bgmType, bool loop, float PlayVolume = -1) | |
{ | |
// ミュートでは無い場合 | |
if (!IsMute) | |
{ | |
// タイトルからインデックスに変換 | |
int index = GetIndex(bgmType, true); | |
// BGMの指定にエラーが起こった場合は終了 | |
if (index < 0 || BGMData.Count <= index) | |
{ | |
return; | |
} | |
// 再生するBGM_Sourcesの番号 | |
int AudioSourceIndex = PlayingNumberSearch(BGM_Sources); | |
// 音量を設定する場合 | |
if (PlayVolume != -1) | |
{ | |
BGM_SoundVolumeSet(bgmType, PlayVolume); | |
} | |
// BGM再生開始 | |
BGM_Sources[AudioSourceIndex].clip = BGMData[index].Clip; | |
BGM_Sources[AudioSourceIndex].loop = loop; | |
BGM_Sources[AudioSourceIndex].volume = BGM_TotalVolume * volume * BGMData[index].SoundVolume; | |
BGM_Sources[AudioSourceIndex].Play(); | |
} | |
} | |
/// <summary> | |
/// BGM再生(オーディオソース指定) | |
/// </summary> | |
/// <param name="bgmType"> BGMのタイトル </param> | |
/// <param name="Source"> オーディオソース </param> | |
/// <param name="loop"> ループの有無 </param> | |
/// <param name="PlayVolume"> 再生時のボリューム </param> | |
public void PlayBGM(string bgmType, ref AudioSource Source, bool loop, float PlayVolume = -1) | |
{ | |
// ミュートでは無い場合 | |
if (!IsMute) | |
{ | |
// タイトルからインデックスに変換 | |
int index = GetIndex(bgmType, true); | |
// BGMの指定にエラーが起こった場合は終了 | |
if (index < 0 || BGMData.Count <= index) | |
{ | |
return; | |
} | |
// 音量を設定する場合 | |
if (PlayVolume != -1) | |
{ | |
BGM_SoundVolumeSet(bgmType, PlayVolume); | |
} | |
// BGM再生開始 | |
Source.clip = BGMData[index].Clip; | |
Source.loop = loop; | |
Source.volume = BGM_TotalVolume * volume * BGMData[index].SoundVolume; | |
Source.Play(); | |
} | |
} | |
/// <summary> | |
/// BGM再生(配列のインデックス直接指定) | |
/// インデックスの確認処理を省いたため、処理は軽くなりました | |
/// </summary> | |
/// <param name="bgmType">BGMのインデックス</param> | |
/// <param name="loop">ループの有無</param> | |
public void PlayBGM(int index, bool loop) | |
{ | |
// 再生するBGM_Sourcesの番号 | |
int AudioSourceIndex = PlayingNumberSearch(BGM_Sources); | |
if (!IsMute) | |
{ | |
// BGM再生開始 | |
BGM_Sources[AudioSourceIndex].clip = BGMData[index].Clip; | |
BGM_Sources[AudioSourceIndex].loop = loop; | |
BGM_Sources[AudioSourceIndex].volume = BGM_TotalVolume * volume * BGMData[index].SoundVolume; | |
BGM_Sources[AudioSourceIndex].Play(); | |
} | |
} | |
/// <summary> | |
/// BGM完全停止 | |
/// </summary> | |
public void StopBGM(string name) | |
{ | |
// 名前から再生停止するBGMを検索する | |
int index = AudioSourceNameToNumber(BGMData.ToArray(), BGM_Sources, name); | |
// BGMが見つかった場合 | |
if (index != -1) | |
{ | |
BGM_Sources[index].Stop(); | |
BGM_Sources[index].clip = null; | |
} | |
} | |
/// <summary> | |
/// 全てのBGMを完全停止 | |
/// </summary> | |
public void StopBGMAll() | |
{ | |
// BGMを検索 | |
for (int i = 0; i < BGM_Sources.Length; i++) | |
{ | |
// nullの場合は以下の処理を行わない | |
if (BGM_Sources[i].clip == null) { continue; } | |
// 全てのBGMを停止 | |
BGM_Sources[i].Stop(); | |
BGM_Sources[i].clip = null; | |
} | |
} | |
/// <summary> | |
/// BGM一時停止 | |
/// </summary> | |
public void MuteBGM(string name) | |
{ | |
// 名前から再生停止するBGMを検索する | |
int index = AudioSourceNameToNumber(BGMData.ToArray(), BGM_Sources, name); | |
// BGMが見つかった場合 | |
if (index != -1) | |
{ | |
BGM_Sources[index].Stop(); | |
} | |
} | |
/// <summary> | |
/// 一時停止した同じBGMを再生(再開) | |
/// </summary> | |
public void ResumeBGM(string name) | |
{ | |
// 名前から再生停止するBGMを検索する | |
int index = AudioSourceNameToNumber(BGMData.ToArray(), BGM_Sources, name); | |
// BGMが見つかった場合 | |
if (index != -1) | |
{ | |
BGM_Sources[index].Play(); | |
} | |
} | |
//============================================================================= | |
// SE系統 | |
//============================================================================= | |
/// <summary> | |
/// SE再生 | |
/// </summary> | |
/// <param name="seType"> 曲名 </param> | |
/// <param name="loop"> ループの有無 </param> | |
/// <param name="PlayVolume"> 再生時のボリューム </param> | |
/// <param name="Singleton"> 同じ曲は再生しない </param> | |
public void PlaySE(string seType, bool loop = false, float PlayVolume = -1, bool Singleton = false) | |
{ | |
// ミュートでは無い場合 | |
if (!IsMute) | |
{ | |
// タイトルからインデックスに変換 | |
int index = GetIndex(seType, false); | |
// SEの指定にエラーが起こった場合は終了 | |
if (index < 0 || SEData.Count <= index) | |
{ | |
return; | |
} | |
// 単体設定の場合はAudioSourceを検索して、同じ名前があったら再生しない | |
if (Singleton) | |
{ | |
foreach (var SE in SE_Sources) | |
{ | |
// 存在しない場合は以下の処理を行わない | |
if (SE.clip == null) { continue; } | |
// AudioSourceから検索 | |
if (SE.clip.name.Equals(SEData[index].Clip.name) && | |
SE.time != 0.0f && | |
SE.isPlaying) | |
{ | |
// 同じ名前が見つかった場合は終了 | |
return; | |
} | |
} | |
} | |
// 音量を設定する場合 | |
if (PlayVolume != -1) | |
{ | |
SE_SoundVolumeSet(seType, PlayVolume); | |
} | |
// 再生するBGM_Sourcesの番号 | |
int AudioSourceIndex = PlayingNumberSearch(SE_Sources); | |
// SE再生開始 | |
SE_Sources[AudioSourceIndex].clip = SEData[index].Clip; | |
SE_Sources[AudioSourceIndex].volume = SE_TotalVolume * volume * SEData[index].SoundVolume; | |
SE_Sources[AudioSourceIndex].loop = loop; | |
SE_Sources[AudioSourceIndex].Play(); | |
} | |
} | |
/// <summary> | |
/// SE再生(オーディオソース指定) | |
/// </summary> | |
/// <param name="seType"> 曲名 </param> | |
/// <param name="Source"> オーディオソース(参照) </param> | |
/// <param name="loop"> ループの有無 </param> | |
/// <param name="PlayVolume"> 再生時のボリューム </param> | |
public void PlaySE(string seType, ref AudioSource Source, bool loop = false, float PlayVolume = -1) | |
{ | |
// ミュートでは無い場合 | |
if (!IsMute) | |
{ | |
// タイトルからインデックスに変換 | |
int index = GetIndex(seType, false); | |
// SEの指定にエラーが起こった場合は終了 | |
if (index < 0 || SEData.Count <= index) | |
{ | |
return; | |
} | |
// 音量を設定する場合 | |
if (PlayVolume != -1) | |
{ | |
SE_SoundVolumeSet(seType, PlayVolume); | |
} | |
// SE再生開始 | |
Source.clip = SEData[index].Clip; | |
Source.volume = SE_TotalVolume * volume * SEData[index].SoundVolume; | |
Source.loop = loop; | |
Source.Play(); | |
} | |
} | |
/// <summary> | |
/// SE再生(配列のインデックス直接指定) | |
/// インデックスの確認処理を省いたため、処理は軽くなりました | |
/// </summary> | |
/// <param name="bgmType">SEのインデックス</param> | |
public void PlaySE(int index) | |
{ | |
// 再生するBGM_Sourcesの番号 | |
int AudioSourceIndex = PlayingNumberSearch(SE_Sources); | |
if (!IsMute) | |
{ | |
// SE再生開始 | |
SE_Sources[AudioSourceIndex].clip = SEData[index].Clip; | |
SE_Sources[AudioSourceIndex].volume = SE_TotalVolume * volume * SEData[index].SoundVolume; | |
SE_Sources[AudioSourceIndex].Play(); | |
} | |
} | |
/// <summary> | |
/// SE停止 | |
/// </summary> | |
public void StopSE(string name) | |
{ | |
// 名前から再生停止するSEを検索する | |
int index = AudioSourceNameToNumber(SEData.ToArray(), SE_Sources, name); | |
// SEが見つかった場合 | |
if (index != -1) | |
{ | |
SE_Sources[index].Stop(); | |
SE_Sources[index].clip = null; | |
} | |
} | |
/// <summary> | |
/// 全てのSEを完全停止 | |
/// </summary> | |
public void StopSEAll() | |
{ | |
// SEを検索 | |
for (int i = 0; i < SE_Sources.Length; i++) | |
{ | |
// nullの場合は以下の処理を行わない | |
if (SE_Sources[i].clip == null) { continue; } | |
// 全てのBGMを停止 | |
SE_Sources[i].Stop(); | |
SE_Sources[i].clip = null; | |
} | |
} | |
public string GetSourceName(string name) | |
{ | |
foreach (AudioData Audio in SEData) | |
{ | |
if (FindTitleMatch(Audio, name)) { return Audio.name; } | |
} | |
return ""; | |
} | |
public void PauseSEAll() | |
{ | |
foreach (var SE in SE_Sources) | |
{ | |
SE.Pause(); | |
} | |
} | |
public void PauseReleaseSEAll() | |
{ | |
foreach (var SE in SE_Sources) | |
{ | |
if (SE.time != 0.0f && !SE.isPlaying) | |
{ | |
SE.Play(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment