Jeremy Smitherman 1523485fe2 feat/state (#2)
Reviewed-on: #2
Co-authored-by: Jeremy Smitherman <Jeremysmitherman@gmail.com>
Co-committed-by: Jeremy Smitherman <Jeremysmitherman@gmail.com>
2026-04-24 18:57:06 +00:00

96 lines
2.9 KiB
C#

using System.Collections;
using UnityEngine;
namespace Management
{
/// <summary>
/// Singleton pattern object that holds an audio source, designed as single source of
/// truth and driver for the BGM music.
/// </summary>
[RequireComponent(typeof(AudioSource))]
public class BGM : MonoBehaviour
{
// hold a static reference to enforce singleton pattern
private static BGM _instance;
// the audiosource that will play the music
private AudioSource _audioSource;
// get the original volume set in the editor so when we fade in/out we know
// what volume to return to.
private float _originalVolume;
// Fades out the currently playing music if playing, then fades in
// the provided clip over the amount of time specified.
// if t == 0 swap is instant.
public void FadeIn(AudioClip clip, float t = 1f)
{
if (clip == null)
{
Debug.LogWarning("BGM: Selected clip is null");
return;
}
StopAllCoroutines();
if (t <= 0)
{
_audioSource.Stop();
_audioSource.clip = clip;
_audioSource.Play();
_audioSource.volume = _originalVolume;
}
else
{
StartCoroutine(FadeInRoutine(clip, t));
}
}
private IEnumerator FadeInRoutine(AudioClip clip, float t)
{
var timer = 0f;
var startVolume = _audioSource.volume;
var fadeInTarget = _audioSource.isPlaying ? t / 2f : t;
if (_audioSource.isPlaying)
{
while (timer < t / 2f)
{
timer += Time.deltaTime;
_audioSource.volume = Mathf.Lerp(startVolume, 0f, timer / (t / 2f));
yield return null;
}
_audioSource.volume = 0f;
timer = 0f;
}
_audioSource.Stop();
_audioSource.clip = clip;
_audioSource.Play();
while (timer < fadeInTarget)
{
timer += Time.deltaTime;
_audioSource.volume = Mathf.Lerp(0f, _originalVolume, timer / fadeInTarget);
yield return null;
}
_audioSource.volume = _originalVolume;
}
private void Awake()
{
// enforce singleton
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
_instance = this;
_audioSource = GetComponent<AudioSource>();
_originalVolume = _audioSource.volume;
DontDestroyOnLoad(gameObject);
}
}
}