EscapeShooter/My project/Assets/Project Files/Modules/Audio/Scripts/Runtime/MusicSource.cs

154 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using UnityEngine;
namespace Watermelon
{
[RequireComponent(typeof(AudioSource))]
public class MusicSource : MonoBehaviour
{
private const float DEFAULT_FADE_DURATION = 0.3f;
private static MusicSource defaultMusicSource;
private static MusicSource activeMusicSource;
public static MusicSource ActiveMusicSource => activeMusicSource;
[SerializeField] bool activateAutomatically = false;
private AudioSource audioSource;
public AudioSource AudioSource => audioSource;
// Raw 0–1 volume, independent of global volume and volumeMultiplier
private float currentRawVolume = 0f;
private Coroutine fadeCoroutine;
private float volumeMultiplier = 1.0f;
private bool isInitialized;
private void Start()
{
if(activateAutomatically)
{
Init();
Activate();
}
}
public void Init()
{
if (isInitialized) return;
isInitialized = true;
audioSource = GetComponent<AudioSource>();
audioSource.loop = true;
audioSource.playOnAwake = false;
volumeMultiplier = audioSource.volume;
currentRawVolume = 0f;
audioSource.volume = 0f;
AudioController.VolumeChanged += OnVolumeChanged;
}
public void Unload()
{
if (!isInitialized) return;
if (fadeCoroutine != null)
{
StopCoroutine(fadeCoroutine);
fadeCoroutine = null;
}
AudioController.VolumeChanged -= OnVolumeChanged;
isInitialized = false;
}
private void OnDestroy()
{
Unload();
}
public void SetAsDefault()
{
defaultMusicSource = this;
}
public void Activate()
{
if (activeMusicSource == this) return;
if(activeMusicSource != null)
{
activeMusicSource.audioSource.volume = 0.0f;
activeMusicSource.audioSource.Stop();
activeMusicSource.currentRawVolume = 0f;
}
audioSource.Play();
Fade(1.0f, DEFAULT_FADE_DURATION);
activeMusicSource = this;
}
public void SetVolume(float volume)
{
currentRawVolume = volume;
audioSource.volume = volume * AudioController.GetVolume(AudioType.Music) * volumeMultiplier;
}
public void Fade(float targetVolume, float duration, float delay = 0, SimpleCallback onComplete = null)
{
if (fadeCoroutine != null)
StopCoroutine(fadeCoroutine);
fadeCoroutine = StartCoroutine(FadeRoutine(targetVolume, duration, delay, onComplete));
}
private IEnumerator FadeRoutine(float target, float duration, float delay, SimpleCallback onComplete)
{
if (delay > 0f)
yield return new WaitForSeconds(delay);
float start = currentRawVolume;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
currentRawVolume = Mathf.Lerp(start, target, Mathf.Clamp01(elapsed / duration));
audioSource.volume = currentRawVolume * AudioController.GetVolume(AudioType.Music) * volumeMultiplier;
yield return null;
}
currentRawVolume = target;
audioSource.volume = currentRawVolume * AudioController.GetVolume(AudioType.Music) * volumeMultiplier;
fadeCoroutine = null;
onComplete?.Invoke();
}
private void OnVolumeChanged(AudioType audioType, float volume)
{
if (audioType != AudioType.Music) return;
audioSource.volume = currentRawVolume * volume * volumeMultiplier;
}
public bool IsActive()
{
return activeMusicSource == this;
}
public static void ActivateDefault()
{
if (activeMusicSource == defaultMusicSource) return;
if (defaultMusicSource != null)
defaultMusicSource.Activate();
}
}
}