RiftMayhem/Assets/Scripts/Audio/MusicFader.cs
2025-06-06 22:08:13 +01:00

111 lines
2.7 KiB
C#

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()
{
currentClip = null;
OnNewSceneLoaded_AudioRequest_AudioEvent.Response.AddListener(FadeOutAndIntoNewMusic);
}
private void Start()
{
if (audioSource == null)
{
audioSource = GetComponent<AudioSource>();
}
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();
}
}