using System; using System.Collections.Generic; using UnityEngine; public class AudioManager : Singleton { [SerializeField] private AudioSource musicSource; [SerializeField] private AudioSource introSource; private bool backgroundMusicShouldPlay = true; private bool backgroundMusicEnabled = true; private bool narrationEnabled = true; private bool introIsActive; private readonly List activeIntroClips = new(); public bool NarrationEnabled => narrationEnabled; public AudioClip CurrentIntroClip => introIsActive && introSource != null ? introSource.clip : null; public event Action NarrationEnabledChanged; public event Action ActiveIntroChanged; protected override void Awake() { base.Awake(); musicSource ??= GetComponent(); if (introSource != null) { narrationEnabled = !introSource.mute; } } private void Update() { if (introIsActive && (introSource == null || !introSource.isPlaying)) { AudioClip previousIntroClip = CurrentIntroClip; if (introSource != null) { activeIntroClips.Remove(introSource.clip); } introIsActive = false; ApplyBackgroundMusicState(); NotifyActiveIntroChanged(previousIntroClip); } } public void PlayBackgroundMusic() { backgroundMusicShouldPlay = true; ApplyBackgroundMusicState(); } public void PauseBackgroundMusic() { backgroundMusicShouldPlay = false; ApplyBackgroundMusicState(); } public void SetBackgroundMusicEnabled(bool isEnabled) { backgroundMusicEnabled = isEnabled; ApplyBackgroundMusicState(); } public void SetNarrationEnabled(bool isEnabled) { AudioClip previousIntroClip = CurrentIntroClip; narrationEnabled = isEnabled; if (introSource != null) { introSource.mute = false; if (!narrationEnabled) { activeIntroClips.Clear(); introSource.Stop(); } } if (!narrationEnabled) { introIsActive = false; ApplyBackgroundMusicState(); NotifyActiveIntroChanged(previousIntroClip); } NarrationEnabledChanged?.Invoke(narrationEnabled); } public void PlayArtWorkIntro(AudioClip introClip) { if (!narrationEnabled || introSource == null || introClip == null) { return; } if (!activeIntroClips.Contains(introClip)) { activeIntroClips.Add(introClip); } ApplyActiveIntroState(); } public void PauseArtWorkIntro(AudioClip introClip) { if (introClip == null) { return; } activeIntroClips.Remove(introClip); ApplyActiveIntroState(); } private void ApplyActiveIntroState() { AudioClip previousIntroClip = CurrentIntroClip; AudioClip nextIntroClip = activeIntroClips.Count > 0 ? activeIntroClips[activeIntroClips.Count - 1] : null; if (introSource == null || nextIntroClip == null) { if (introSource != null && introSource.isPlaying) { introSource.Pause(); } introIsActive = false; ApplyBackgroundMusicState(); NotifyActiveIntroChanged(previousIntroClip); return; } if (introSource.clip != nextIntroClip) { introSource.clip = nextIntroClip; introSource.Play(); } else { introSource.UnPause(); if (!introSource.isPlaying) { introSource.Play(); } } introIsActive = true; ApplyBackgroundMusicState(); NotifyActiveIntroChanged(previousIntroClip); } private void NotifyActiveIntroChanged(AudioClip previousIntroClip) { if (previousIntroClip != CurrentIntroClip) { ActiveIntroChanged?.Invoke(); } } private void ApplyBackgroundMusicState() { if (musicSource == null) { return; } if (!backgroundMusicEnabled || !backgroundMusicShouldPlay || introIsActive) { if (musicSource.isPlaying) { musicSource.Pause(); } return; } if (musicSource.isPlaying) { return; } musicSource.UnPause(); if (!musicSource.isPlaying) { musicSource.Play(); } } }