using System; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Serialization; using Utility; public class MusicManager : MonoBehaviourSingleton { [SerializeField] private List _ambientMusic; [FormerlySerializedAs("_showDownMusic")] [SerializeField] private AudioClip _winningMusic; [SerializeField] private AudioClip _losingMusic; [SerializeField, ShowOnly] private float _musicTimer = 5f; private float _musicCheckInterval = 30f; private AudioSource _audioSource; private AudioClip _currentlyPlaying; private float _defaultVolume; private ShowDown _showDown = ShowDown.NotYet; private bool _doneFading = false; private bool _showDownIsPlaying = false; private enum ShowDown { NotYet, AlmostFinished, TimesRunningOut } // Start is called before the first frame update void Start() { _audioSource = GetComponent(); _defaultVolume = _audioSource.volume; } // Update is called once per frame void Update() { CheckForFinalMusic(); if (_showDown == ShowDown.NotYet) { _musicTimer -= Time.deltaTime; if (_musicTimer <= 0) { _musicTimer = _musicCheckInterval; if (!_audioSource.isPlaying) { PlayNewMusic(); } } } } private void FadeOutMusic() { _audioSource.volume -= _audioSource.volume * Time.deltaTime; _audioSource.volume = _audioSource.volume <= 0.05f ? 0.0f : _audioSource.volume; _doneFading = _audioSource.volume <= 0.05f; } private void CheckForFinalMusic() { ShowDown oldShowDown = _showDown; if (TimeManager.Instance.RealLifeSecondsUntilDeadline < 100) { _showDown = ShowDown.TimesRunningOut; } else if (GameManager.Instance.GameProgress > 0.85) { _showDown = ShowDown.AlmostFinished; } else { _showDown = ShowDown.NotYet; } if (!GameManager.Instance.IsStarted) { _showDown = ShowDown.NotYet; } if (oldShowDown != _showDown) { switch (_showDown) { case ShowDown.NotYet: FadeToClip(_ambientMusic.GetRandomElement()); break; case ShowDown.AlmostFinished: FadeToClip(_winningMusic); break; case ShowDown.TimesRunningOut: FadeToClip(_losingMusic); break; } } } private void FadeToClip(AudioClip audioClip) { StartCoroutine(FadeToClipRoutine(audioClip)); } [SerializeField] private float _fadeDuration = 1.0f; private IEnumerator FadeToClipRoutine(AudioClip audioClip) { float currentTime = 0; float start = _audioSource.volume; while (currentTime < _fadeDuration) { currentTime += Time.deltaTime; _audioSource.volume = Mathf.Lerp(start, 0.0f, currentTime / _fadeDuration); yield return null; } _audioSource.Stop(); _audioSource.volume = _defaultVolume; _audioSource.clip = audioClip; _audioSource.loop = true; _audioSource.Play(); } private void PlayNewMusic() { if (_currentlyPlaying == null) { _audioSource.clip = _ambientMusic.GetRandomElement(); _audioSource.Play(); } else { _ambientMusic.Remove(_currentlyPlaying); AudioClip newMusic = _ambientMusic.GetRandomElement(); _ambientMusic.Add(_currentlyPlaying); _audioSource.clip = newMusic; _audioSource.Play(); } } }