using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; namespace TON { public class SoundManager : MonoBehaviour { [Header("#BGM")] public AudioClip bgmClip; public float bgmVolume; AudioSource bgSound; [Header("#SFX")] public float sfxVolume; AudioSource sfxSound; public static SoundManager instance; // 현재 재생 중인 SFX 클립과 해당 AudioSource를 저장할 Dictionary private Dictionary playingSfxMap = new Dictionary(); private void Awake() { if (instance == null) { instance = this; Init(); DontDestroyOnLoad(instance); // 씬 로드 이벤트에 리스너 등록 SceneManager.sceneLoaded += OnSceneLoaded; } else { Destroy(gameObject); } } void Init() { // 배경음 플레이어 초기화 GameObject bgmObject = new GameObject("BGM"); bgmObject.transform.parent = transform; bgSound = bgmObject.AddComponent(); bgSound.playOnAwake = false; bgSound.loop = true; bgSound.volume = bgmVolume; bgSound.clip = bgmClip; // 호과음 플레이어 초기화 GameObject sfxObject = new GameObject("SFX"); sfxObject.transform.parent = transform; sfxSound = sfxObject.AddComponent(); sfxSound.playOnAwake = false; sfxSound.volume = sfxVolume; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 씬이 바뀔 때마다 배경 음악 종료 BgSoundPlay(null); foreach (var entry in playingSfxMap) { if (entry.Value != null && entry.Value.gameObject != null) { Destroy(entry.Value.gameObject); } } playingSfxMap.Clear(); } public void SFXPlay(string sfxName, AudioClip clip) { // 재생 중인지 확인 if (playingSfxMap.ContainsKey(clip) && playingSfxMap[clip].isPlaying) { Debug.Log($"SFX '{sfxName}' 재생중이므로 재생하지 않고 넘김."); return; // 이미 재생 중이면 재생하지 않고 종료 } GameObject go = new GameObject(sfxName + "Sound"); AudioSource audiosource = go.AddComponent(); audiosource.clip = clip; audiosource.volume = sfxVolume; // SFX 볼륨 적용 audiosource.Play(); playingSfxMap[clip] = audiosource; StartCoroutine(DestroyAndRemoveSFX(go, clip, clip.length)); } private IEnumerator DestroyAndRemoveSFX(GameObject go, AudioClip clip, float delay) { yield return new WaitForSeconds(delay); if (playingSfxMap.ContainsKey(clip) && playingSfxMap[clip] == go.GetComponent()) { playingSfxMap.Remove(clip); } Destroy(go); } public void BgSoundPlay(AudioClip clip) { bgSound.clip = clip; bgSound.loop = true; bgSound.volume = 1f; bgSound.Play(); } } }