using System.Collections.Generic; using UnityEngine; public enum ESFXType { Button_Hit, Bbug_1, Bbug_2, Bring_Card_1, Bring_Card_2, Bring_Card_3, Bring_Card_4, CardMove_1, CardMove_2, CardMove_3, Clean_2, Clear_1, Card_Hit, Card_NoHit, FlipCard_Hit, Godori_1, Godori_2, Start_1, Start_2, Start_3, Lose, Win, Win_2, Bee_Three_Ghwang, Three_Gwhang_1, Three_Gwhang_2, Four_Ghwang, Five_Ghwang, Ddadag_1, Ddadag_2, Hongdan_1, Hongdan_2, Chungdan_1, Chungdan_2, Chodan_1, Chodan_2, Bomb_1, Bomb_2, Bomb_3, Kiss, Shake, Bonus, Open_Popup, Stamp, Max } public enum EVoiceType { Bomb_Voice, Chodan_Voice, Chungdan_Voice, Godori_Voice, Hongdan_Voice, Chongtong_Voice, Ddadag_Voice, Nagari_Voice, Go_1_Voice, Go_2_Voice, Go_3_Voice, Go_4_Voice, Go_5_Voice, Go_6_Voice, Go_7_Voice, Go_8_Voice, Go_9_Voice, Stop_1_Voice, Stop_2_Voice, Win_Voice, Lose_Voice, Be_Three_Gwhang, Samgwang_Voice, Sagwang_Voice, Ogwang_Voice, Bbug_1_Voice, Bbug_2_Voice, Shake_Voice, Kiss_Voice, Clear_Voice_1, Clear_Voice_2, Max } public enum EBGMType { BGM_1, BGM_2, BGM_HUNT_1, BGM_HUNT_2, BGM_PROLOGUE_1, Max } public class SoundManager : MonoBehaviour { #region Defines private const string BGM_PATH = "Sounds/BGM"; private const string SFX_PATH = "Sounds/SFX"; private const string VOICE_PATH = "Sounds/Voice"; private const float BGM_FADE_DURATION = 1f / 2f; private const int SFX_AUDIOSOURCE_MAX = 25; private const int VOICE_AUDIOSOURCE_MAX = 3; #endregion #region Classes [System.Serializable] public class SoundReserveData { public int typeIndex; public float delay; public SoundReserveData(int Index, float d) { this.typeIndex = Index; this.delay = d; } } #endregion #region Fields private EBGMType CurrentEBGMType = EBGMType.Max; private Dictionary _dicBGMClips; private Dictionary _dicSFXClips; private Dictionary _dicVoiceClips; private AudioSource _bgmSource; private List _lstSFXSources; private List _lstVoiceSources; private Dictionary _dicBGMVolumes; private Dictionary _dicSFXVolumes; private int _sfxIndex = 0; private int _voiceIndex = 0; private System.Collections.IEnumerator _eReserveSFX; private List _lstReservedSFXList; #endregion #region Properties public bool BGM_Mute { get; private set; } = false; public bool SFX_Mute { get; private set; } = false; #endregion private void Awake() { _lstReservedSFXList = new List(); this.Initialize(); this.LoadSounds(); } private void Start() { this.BGMMute(GameManager.DB.BGMMute); this.SFXMute(GameManager.DB.SFXMute); } private void OnDestroy() { if (_eReserveSFX != null) StopCoroutine(_eReserveSFX); } private void LoadSounds() { var SFXClips = Resources.LoadAll(SFX_PATH); _dicSFXClips = new Dictionary(); for (int i = 0; i < SFXClips.Length; i++) { ESFXType sfxtype = ESFXType.Max; if (System.Enum.TryParse(SFXClips[i].name, out sfxtype)) { _dicSFXClips.Add(sfxtype, SFXClips[i]); } } var VoideClips = Resources.LoadAll(VOICE_PATH); _dicVoiceClips = new Dictionary(); for (int i = 0; i < VoideClips.Length; i++) { EVoiceType voiceType = EVoiceType.Max; if (System.Enum.TryParse(VoideClips[i].name, out voiceType)) { _dicVoiceClips.Add(voiceType, VoideClips[i]); } } var BGMClips = Resources.LoadAll(BGM_PATH); _dicBGMClips = new Dictionary(); for (int i = 0; i < BGMClips.Length; i++) { EBGMType bgmType = EBGMType.Max; if (System.Enum.TryParse(BGMClips[i].name, out bgmType)) { _dicBGMClips.Add(bgmType, BGMClips[i]); } } } private void Initialize() { #region Set Audio Sources ================================================ _bgmSource = new GameObject("BGM").AddComponent(); _bgmSource.loop = true; _bgmSource.spatialBlend = 0f; _bgmSource.dopplerLevel = 0f; _bgmSource.minDistance = 10000f; _bgmSource.maxDistance = 10000f; _bgmSource.transform.SetParent(this.transform); _lstSFXSources = new List(); _lstSFXSources.Capacity = SFX_AUDIOSOURCE_MAX; for (int i = 0; i < SFX_AUDIOSOURCE_MAX; i++) { AudioSource Source = new GameObject("SFX_Source" + (i + 1).ToString()).AddComponent(); _lstSFXSources.Add(Source); _lstSFXSources[i].loop = false; _lstSFXSources[i].spatialBlend = 0f; _lstSFXSources[i].dopplerLevel = 0f; _lstSFXSources[i].volume = 1; _lstSFXSources[i].minDistance = 10000f; _lstSFXSources[i].maxDistance = 10000f; _lstSFXSources[i].transform.SetParent(this.transform); } _lstVoiceSources = new List(); _lstVoiceSources.Capacity = SFX_AUDIOSOURCE_MAX; for (int i = 0; i < SFX_AUDIOSOURCE_MAX; i++) { AudioSource Source = new GameObject("Voice_Source" + (i + 1).ToString()).AddComponent(); _lstVoiceSources.Add(Source); _lstVoiceSources[i].loop = false; _lstVoiceSources[i].spatialBlend = 0f; _lstVoiceSources[i].dopplerLevel = 0f; _lstVoiceSources[i].volume = 1; _lstVoiceSources[i].minDistance = 10000f; _lstVoiceSources[i].maxDistance = 10000f; _lstVoiceSources[i].transform.SetParent(this.transform); } #endregion #region Set Volume Data _dicBGMVolumes = new Dictionary(); _dicSFXVolumes = new Dictionary(); #endregion } /// True is Stop BGM. public void BGMMute(bool b) { BGM_Mute = b; if (BGM_Mute) { _bgmSource.volume = 0; } else { _bgmSource.volume = GetBGMVolume(CurrentEBGMType); } } public void SFXMute(bool b) { SFX_Mute = b; } public void PlayBGM(EBGMType type) { if (BGM_Mute) return; if (type == CurrentEBGMType) return; if (_dicBGMClips.ContainsKey(type)) { CurrentEBGMType = type; _bgmSource.clip = _dicBGMClips[type]; _bgmSource.loop = true; _bgmSource.volume = GetBGMVolume(type); _bgmSource.Play(); } } public void PlaySFX(ESFXType sfx) { if (SFX_Mute) return; if (_dicSFXClips.ContainsKey(sfx)) { AudioSource source = GetSFXAudioSource(); source.clip = GetSFXClip(sfx); source.loop = false; source.volume = GetSFXVolume(sfx); source.Play(); } } public void PlayGoVoice(int go) { EVoiceType type = EVoiceType.Go_1_Voice + (go - 1); if (go >= 9) type = EVoiceType.Go_9_Voice; this.PlayVoice(type); } public void PlayVoice(EVoiceType voiceType) { if (SFX_Mute) return; if (_dicVoiceClips.ContainsKey(voiceType)) { AudioSource source = GetVoiceAudioSource(); source.clip = GetVoiceClip(voiceType); source.loop = false; source.volume = 1; source.Play(); } } public void ReserveSFX(ESFXType type, float delay) { _lstReservedSFXList.Add(new SoundReserveData((int)type, delay)); if (_eReserveSFX == null) { _eReserveSFX = this.coroReserveSFX(); StartCoroutine(_eReserveSFX); } } #region Core private AudioClip GetSFXClip(ESFXType sfxType) { switch (sfxType) { case ESFXType.Bbug_1: case ESFXType.Bbug_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Bbug_1] : _dicSFXClips[ESFXType.Bbug_2]; } case ESFXType.Bring_Card_1: case ESFXType.Bring_Card_2: case ESFXType.Bring_Card_3: case ESFXType.Bring_Card_4: { int rnd = Random.Range(0, 4); if (rnd == 0) return _dicSFXClips[ESFXType.Bring_Card_1]; else if (rnd == 1) return _dicSFXClips[ESFXType.Bring_Card_2]; else if (rnd == 2) return _dicSFXClips[ESFXType.Bring_Card_3]; else return _dicSFXClips[ESFXType.Bring_Card_4]; } case ESFXType.CardMove_1: case ESFXType.CardMove_2: case ESFXType.CardMove_3: { int rnd = Random.Range(0, 3); if (rnd == 0) return _dicSFXClips[ESFXType.CardMove_1]; else if (rnd == 1) return _dicSFXClips[ESFXType.CardMove_2]; else return _dicSFXClips[ESFXType.CardMove_3]; } case ESFXType.Clear_1: case ESFXType.Clean_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Clear_1] : _dicSFXClips[ESFXType.Clean_2]; } case ESFXType.Godori_1: case ESFXType.Godori_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Godori_1] : _dicSFXClips[ESFXType.Godori_2]; } case ESFXType.Start_1: case ESFXType.Start_2: case ESFXType.Start_3: { int rnd = Random.Range(0, 3); if (rnd == 0) return _dicSFXClips[ESFXType.Start_1]; else if (rnd == 1) return _dicSFXClips[ESFXType.Start_2]; else return _dicSFXClips[ESFXType.Start_3]; } case ESFXType.Bomb_1: case ESFXType.Bomb_2: case ESFXType.Bomb_3: { int rnd = Random.Range(0, 3); if (rnd == 0) return _dicSFXClips[ESFXType.Bomb_1]; else if (rnd == 1) return _dicSFXClips[ESFXType.Bomb_2]; else return _dicSFXClips[ESFXType.Bomb_3]; } case ESFXType.Three_Gwhang_1: case ESFXType.Three_Gwhang_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Three_Gwhang_1] : _dicSFXClips[ESFXType.Three_Gwhang_2]; } case ESFXType.Ddadag_1: case ESFXType.Ddadag_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Ddadag_1] : _dicSFXClips[ESFXType.Ddadag_2]; } case ESFXType.Hongdan_1: case ESFXType.Hongdan_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Hongdan_1] : _dicSFXClips[ESFXType.Hongdan_2]; } case ESFXType.Chungdan_1: case ESFXType.Chungdan_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Chungdan_1] : _dicSFXClips[ESFXType.Chungdan_2]; } case ESFXType.Chodan_1: case ESFXType.Chodan_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicSFXClips[ESFXType.Chodan_1] : _dicSFXClips[ESFXType.Chodan_2]; } default: return _dicSFXClips[sfxType]; } } private AudioSource GetSFXAudioSource() { if (_sfxIndex >= SFX_AUDIOSOURCE_MAX) _sfxIndex = 0; return _lstSFXSources[_sfxIndex++]; } private float GetSFXVolume(ESFXType sfxType) { switch (sfxType) { case ESFXType.CardMove_1: return 0.3f; case ESFXType.Button_Hit: return 0.5f; case ESFXType.Win: return 0.5f; case ESFXType.Win_2: return 0.5f; default: return 1f; } } private AudioClip GetVoiceClip(EVoiceType voiceType) { switch (voiceType) { case EVoiceType.Stop_1_Voice: case EVoiceType.Stop_2_Voice: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicVoiceClips[EVoiceType.Stop_1_Voice] : _dicVoiceClips[EVoiceType.Stop_2_Voice]; } case EVoiceType.Bbug_1_Voice: case EVoiceType.Bbug_2_Voice: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicVoiceClips[EVoiceType.Bbug_1_Voice] : _dicVoiceClips[EVoiceType.Bbug_2_Voice]; } case EVoiceType.Clear_Voice_1: case EVoiceType.Clear_Voice_2: { int rnd = Random.Range(0, 2); return rnd == 0 ? _dicVoiceClips[EVoiceType.Clear_Voice_1] : _dicVoiceClips[EVoiceType.Clear_Voice_2]; } default: return _dicVoiceClips[voiceType]; } } private AudioSource GetVoiceAudioSource() { if (_voiceIndex >= VOICE_AUDIOSOURCE_MAX) _voiceIndex = 0; return _lstVoiceSources[_voiceIndex++]; } private System.Collections.IEnumerator coroReserveSFX() { while (_lstReservedSFXList.Count > 0) { for (int i = _lstReservedSFXList.Count - 1; i >= 0; i--) { _lstReservedSFXList[i].delay -= Time.deltaTime * GamePanel.GameSpeed; if (_lstReservedSFXList[i].delay < 0) { PlaySFX((ESFXType)_lstReservedSFXList[i].typeIndex); _lstReservedSFXList.RemoveAt(i); } } yield return null; } _eReserveSFX = null; } private float GetBGMVolume(EBGMType type) { switch (type) { case EBGMType.BGM_1: return 0.5f; case EBGMType.BGM_2: return 0.35f; default: return 0.5f; } } #endregion }