using System; using System.Collections; using UnityEngine; namespace Audio { public class AudioManager : MonoBehaviour { public static AudioManager instance; [SerializeField] private Sounds soundList; private void Awake() { if (instance == null) { instance = this; } else { Destroy(gameObject); return; } DontDestroyOnLoad(gameObject); foreach (Sounds.List s in soundList.sounds) { if (string.IsNullOrEmpty(s.name) || string.IsNullOrWhiteSpace(s.name)) { Debug.LogWarning("The name one sound is empty"); continue; } GameObject sound = new(s.name) { transform = { parent = transform } }; s.source = sound.AddComponent(); if (soundList.musicMixer && soundList.sfxMixer) { s.source.outputAudioMixerGroup = s.type == Sounds.List.Type.Music ? soundList.musicMixer : soundList.sfxMixer; } s.source.clip = s.clip; s.source.volume = s.volume; s.source.pitch = s.pitch; s.source.loop = s.loop; } } #region Play /// Use this to play a sound with a specific name /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void Play(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.Play(); } /// Use this to play a sound with a specific name and with a certain delay /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound /// The delay in seconds public void Play(string name, float delay) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.PlayDelayed(delay); } /// Use this to play one shot of a sound with a specific name /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void PlayOneShot(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.PlayOneShot(s.clip); } /// Use this to play an intro song and then start playing the song loop /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the intro song /// The name of the song loop public void PlayWithIntro(string intro, string song) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == intro); if (s == null) { Debug.LogWarning("Sound: " + intro + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.Play(); float introDuration = s.clip.length; Play(song, introDuration); } /// Use this to play one shot of a random sound within a list /// They have to be in the Sound asset referenced in the AudioManager instance /// /// The names of the sounds public void PlayRandomSound(params string[] names) { int random = UnityEngine.Random.Range(0, names.Length); PlayOneShot(names[random]); } #endregion #region Pause /// Use this to pause a sound with a specific name /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void Pause(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.Pause(); } /// Use this to unpause a sound with a specific name /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void UnPause(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.UnPause(); } #endregion #region Stop /// Use this to stop a sound with a specific name /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void Stop(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = s.RandomVolume; s.source.Stop(); } /// Use this to stop all the sounds /// It has to be in the Sound asset referenced in the AudioManager instance /// public void StopAll() { foreach (Sounds.List s in soundList.sounds) { if (s.source) { s.source.Stop(); } } } #endregion /// This function returns the AudioSource that contains a specific sound /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound /// The AudioSource in the scene public AudioSource GetSource(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return null; } return s.source; } #region Fades /// Use this to start playing a sound with a fade in /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound /// The duration of the fade in public void FadeIn(string name, float duration) { StartCoroutine(FadeInCoroutine(name, duration)); } IEnumerator FadeInCoroutine(string name, float fadeTime) { AudioSource audioSource = GetSource(name); if (audioSource != null && !audioSource.isPlaying) { float volume = audioSource.volume; audioSource.volume = 0; audioSource.Play(); while (audioSource.volume < volume) { audioSource.volume += Time.deltaTime / fadeTime; yield return null; } audioSource.volume = volume; } } /// Use this to stop playing a sound with a fade out /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound /// The duration of the fade out public void FadeOut(string name, float duration) { StartCoroutine(FadeOutCoroutine(name, duration)); } private IEnumerator FadeOutCoroutine(string name, float fadeTime) { AudioSource audioSource = GetSource(name); if (!audioSource || !audioSource.isPlaying) yield break; float startVolume = audioSource.volume; while (audioSource.volume > 0) { audioSource.volume -= startVolume * Time.deltaTime / fadeTime; yield return null; } audioSource.Stop(); audioSource.volume = startVolume; } /// Use this to start playing a sound muted /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound public void PlayMuted(string name) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; } s.source.pitch = s.RandomPitch; s.source.volume = 0f; s.source.Play(); } /// Use this to fade in a sound that is currently muted /// It has to be in the Sound asset referenced in the AudioManager instance /// WARNING: If the PlayMuted hasn't been called before, this function won't work /// /// The name of the sound /// The duration of the fade in public void FadeMutedIn(string name, float duration) { StartCoroutine(FadeMutedInCoroutine(name, duration)); } private IEnumerator FadeMutedInCoroutine(string name, float fadeTime) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); yield break; } while (s.source.volume < s.volume) { s.source.volume += Time.deltaTime / fadeTime; yield return null; } s.source.volume = s.volume; } /// Use this to fade out a sound and keep playing that muted /// It has to be in the Sound asset referenced in the AudioManager instance /// /// The name of the sound /// The duration of the fade out public void FadeMutedOut(string name, float duration) { StartCoroutine(FadeMutedOutCoroutine(name, duration)); } private IEnumerator FadeMutedOutCoroutine(string name, float fadeTime) { Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); yield break; } while (s.source.volume > 0) { s.source.volume -= Time.deltaTime / fadeTime; yield return null; } s.source.volume = 0; } #endregion } }