using AppleHills.Core.Settings; using Bootstrap; using Core; using PuzzleS; using UnityEngine; using UnityEngine.Audio; using AppleHills.Core; using AppleHills.Core.Interfaces; using System.Collections.Generic; using AudioSourceEvents; using System; public class AudioManager : MonoBehaviour, IPausable { /// /// Play all audio, just music or no audio at all when the game is paused. /// public enum PauseBehavior { PlayAllAudio, MusicOnly, NoAudio } public PauseBehavior currentPauseBehavior; public AudioMixer audioMixer; private AudioListener _audioListener; public AppleAudioSource currentlyPlayingVO; private static AudioManager _instance; private GameObject _player; public List criticalVOSources; public List VOSources; public List musicSources; public List ambienceSources; public List SFXSources; private IAudioEventSource _eventSource; /// /// Singleton instance of the AudioManager. /// public static AudioManager Instance => _instance; void Awake() { _instance = this; // Register for post-boot initialization BootCompletionService.RegisterInitAction(InitializePostBoot); GameManager.Instance.RegisterPausableComponent(this); } private void InitializePostBoot() { } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { _player = QuickAccess.Instance.PlayerGameObject; _audioListener = QuickAccess.Instance.MainCamera.GetComponent(); foreach (AppleAudioSource _audioSource in criticalVOSources) { Debug.Log("Found source: " + _audioSource.name); } } public void SetAudioPauseBehavior(PauseBehavior newPauseBehavior) { switch (newPauseBehavior) { case PauseBehavior.PlayAllAudio: audioMixer.updateMode = AudioMixerUpdateMode.UnscaledTime; AudioListener.pause = false; break; case PauseBehavior.MusicOnly: audioMixer.updateMode = AudioMixerUpdateMode.UnscaledTime; break; //TODO: Pause all audio mixers except music mixer case PauseBehavior.NoAudio: audioMixer.updateMode = AudioMixerUpdateMode.Normal; AudioListener.pause = true; break; } } public LevelAudioObject GetCurrentLevelAudioObject() { Debug.Log("Audio objects: " + FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).Length); if (FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).Length > 1) { Debug.LogWarning("Warning! More than one LevelAudioObject in the level! Using the first one found"); return FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)[0]; } if (FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).Length == 0) { Debug.LogWarning("Error! No LevelAudioObject found, AudioManager might not function properly!"); return null; } else return FindFirstObjectByType(); } public void Pause() { SetAudioPauseBehavior(PauseBehavior.NoAudio); } public void DoResume() { SetAudioPauseBehavior(PauseBehavior.PlayAllAudio); } public void RegisterNewAudioSource(AppleAudioSource newAudioSource) { switch (newAudioSource.audioSourceType) { case AppleAudioSource.AudioSourceType.CriticalVO: criticalVOSources.Add(newAudioSource); break; case AppleAudioSource.AudioSourceType.VO: VOSources.Add(newAudioSource); break; case AppleAudioSource.AudioSourceType.SFX: SFXSources.Add(newAudioSource); break; case AppleAudioSource.AudioSourceType.Ambience: ambienceSources.Add(newAudioSource); break; case AppleAudioSource.AudioSourceType.Music: musicSources.Add(newAudioSource); break; } } /// /// Request playing a VO line. Returns true if whatever is playing is not critical, or weight of requested VO line is lower. /// public bool RequestPlayVO(AppleAudioSource requestedAudioSource) { if (currentlyPlayingVO == null) { currentlyPlayingVO = requestedAudioSource; Debug.Log($"CurrentVO prio: {currentlyPlayingVO.priority} requested VO prio: {requestedAudioSource.priority}"); RegisterStartStopEvents(requestedAudioSource.audioSource); return true; } if(currentlyPlayingVO.audioSourceType != AppleAudioSource.AudioSourceType.CriticalVO) { currentlyPlayingVO.InterruptAudio(requestedAudioSource.name); currentlyPlayingVO = requestedAudioSource; Debug.Log($"CurrentVO prio: {currentlyPlayingVO.priority} requested VO prio: {requestedAudioSource.priority}"); RegisterStartStopEvents(requestedAudioSource.audioSource); return true; } if (currentlyPlayingVO.audioSourceType == AppleAudioSource.AudioSourceType.CriticalVO && currentlyPlayingVO.priority > requestedAudioSource.priority) { currentlyPlayingVO.InterruptAudio(requestedAudioSource.name); Debug.Log($"CurrentVO prio: {currentlyPlayingVO.priority} requested VO prio: {requestedAudioSource.priority}"); currentlyPlayingVO = requestedAudioSource; RegisterStartStopEvents(requestedAudioSource.audioSource); return true; } else { Debug.Log($"CurrentVO prio: {currentlyPlayingVO.priority} requested VO prio: {requestedAudioSource.priority}"); return false; } } private void OnApplicationQuit() { // TODO: Release the handles safely ReleaseAllHandles(); } private void RegisterStartStopEvents(AudioSource audioSource) { if (audioSource.resource == null) { Debug.Log($"AppleAudioSource {audioSource.name} could not register Start and Stop events."); } else { _eventSource = audioSource.RequestEventHandlers(); _eventSource.AudioStopped += OnAudioStopped; _eventSource.AudioStarted += OnAudioStarted; } } private void OnAudioStopped(object sender, EventArgs e) { currentlyPlayingVO = null; _eventSource.AudioStopped -= OnAudioStopped; _eventSource.AudioStarted -= OnAudioStarted; } private void OnAudioStarted(object sender, EventArgs e) { } }