using UnityEngine; using System.Collections; using System; public class MusicFader : MonoBehaviour { [Header("Events:")] [SerializeField] GameEventListener_AudioClip OnNewSceneLoaded_AudioRequest_AudioEvent; [Header("Component:")] public AudioSource audioSource; [Header("Settings:")] public float fadeDuration = 1f; private Coroutine fadeCoroutine; private AudioClip currentClip; float startingMaxVolume; private void Awake() { OnNewSceneLoaded_AudioRequest_AudioEvent.Response.AddListener(FadeOutAndIntoNewMusic); } private void Start() { if (audioSource == null) { audioSource = GetComponent(); } audioSource.loop = true; startingMaxVolume = audioSource.volume; } public void FadeIn(Action callback = null) { StopFade(); fadeCoroutine = StartCoroutine(FadeCoroutine(0f, startingMaxVolume, callback)); } public void FadeOut(Action callback = null) { StopFade(); fadeCoroutine = StartCoroutine(FadeCoroutine(audioSource.volume, 0f, callback)); } private void StopFade() { if (fadeCoroutine != null) { StopCoroutine(fadeCoroutine); } } private IEnumerator FadeCoroutine(float startVolume, float targetVolume, Action callback = null) { float elapsedTime = 0f; audioSource.volume = startVolume; while (elapsedTime < fadeDuration) { elapsedTime += Time.deltaTime; float t = elapsedTime / fadeDuration; audioSource.volume = Mathf.Lerp(startVolume, targetVolume, t); yield return null; } audioSource.volume = targetVolume; if (targetVolume == 0f) { audioSource.Pause(); } else { audioSource.Play(); } if (callback != null) callback.Invoke(); } public void FadeOutAndIntoNewMusic(AudioClip newMusic) { if (newMusic == currentClip) { // If it's the same music, just ensure it's playing and fade in if necessary if (!audioSource.isPlaying) { audioSource.Play(); FadeIn(); } } else { if (audioSource.clip == null) { StartNewMusic(newMusic); return; } FadeOut(() => StartNewMusic(newMusic)); } } private void StartNewMusic(AudioClip newMusic) { audioSource.clip = newMusic; currentClip = newMusic; FadeIn(); } }