From cd49315efc60f90d8b16acd21d14dbada710aa95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A0nh=20Long=20=28Morningstar=20WiIIiam=29?= Date: Tue, 23 Jan 2024 22:43:30 +0700 Subject: [PATCH] feat(background-music): add emmitter and config to play (#25) --- .../AddressableAssetSettings.asset | 4 +- Assets/Scenes/WIP/AudioTestScene.unity | 15 ++++ Assets/Scripts/System/Audio/AudioManager.cs | 24 +++--- .../System/Audio/Emitters/AudioEmitter.cs | 76 +++++++++++++++++++ .../Audio/Emitters/AudioEmitterValue.cs | 22 ++++++ .../Audio/Emitters/AudioEmitterValue.cs.meta | 3 + 6 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs create mode 100644 Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs.meta diff --git a/Assets/AddressableAssetsData/AddressableAssetSettings.asset b/Assets/AddressableAssetsData/AddressableAssetSettings.asset index bf2428b..d04d7dd 100644 --- a/Assets/AddressableAssetsData/AddressableAssetSettings.asset +++ b/Assets/AddressableAssetsData/AddressableAssetSettings.asset @@ -15,7 +15,7 @@ MonoBehaviour: m_DefaultGroup: a6a10e199b443454ba3e0754129e4913 m_currentHash: serializedVersion: 2 - Hash: 383e5346901155784c0510435203ab9f + Hash: 8ab13f72977a6ff07d748a771a2bf865 m_OptimizeCatalogSize: 0 m_BuildRemoteCatalog: 0 m_BundleLocalCatalog: 0 @@ -38,7 +38,7 @@ MonoBehaviour: m_Id: m_RemoteCatalogLoadPath: m_Id: - m_ContentStateBuildPathProfileVariableName: + m_ContentStateBuildPathProfileVariableName: m_CustomContentStateBuildPath: m_ContentStateBuildPath: m_BuildAddressablesWithPlayerBuild: 0 diff --git a/Assets/Scenes/WIP/AudioTestScene.unity b/Assets/Scenes/WIP/AudioTestScene.unity index b8111cd..2a89a77 100644 --- a/Assets/Scenes/WIP/AudioTestScene.unity +++ b/Assets/Scenes/WIP/AudioTestScene.unity @@ -227,6 +227,10 @@ PrefabInstance: propertyPath: m_Name value: AudioManager objectReference: {fileID: 0} + - target: {fileID: 8029590146148956303, guid: 367a3aea81f87844c8a9c1454fce8d1f, type: 3} + propertyPath: _emitter + value: + objectReference: {fileID: 6679447067400465031} - target: {fileID: 8683984623389327866, guid: 367a3aea81f87844c8a9c1454fce8d1f, type: 3} propertyPath: m_LocalPosition.x value: 0 @@ -329,6 +333,17 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: cfe0c4e0865e4374b93e8f32ef301852, type: 3} +--- !u!114 &6679447067400465031 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 4367108581900793607, guid: cfe0c4e0865e4374b93e8f32ef301852, type: 3} + m_PrefabInstance: {fileID: 6679447067400465030} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76e0b6e43a6b4db79a466d5fc32e0f61, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1001 &7240087349313893617 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/System/Audio/AudioManager.cs b/Assets/Scripts/System/Audio/AudioManager.cs index ee88354..3eec576 100644 --- a/Assets/Scripts/System/Audio/AudioManager.cs +++ b/Assets/Scripts/System/Audio/AudioManager.cs @@ -9,8 +9,9 @@ public class AudioManager : MonoBehaviour { [SerializeField] private AudioCueEventChannelSO _musicEventChannel; + [SerializeField] private AudioEmitter _emitter; - private AudioEmitter _playingMusicAudioEmitter; + private AudioEmitter _musicEmitter; private AudioCueSO _currentBgmCue; private void OnEnable() @@ -38,28 +39,31 @@ private void PlayMusic(AudioCueSO audioToPlay, bool requestPlay) private void HandleMusicToPlay(AudioCueSO audioToPlay) { + float startTime = 0f; + if (_currentBgmCue != null) { _currentBgmCue.GetPlayableAsset().ReleaseAsset(); } - AudioHelper.TryToLoadData(audioToPlay, currentClip => + void OnAudioClipLoaded(AudioClip currentClip) { if (IsAudioPlaying()) { AudioClip musicToPlay = currentClip; - if (_playingMusicAudioEmitter.GetClip() == musicToPlay) return; + if (_musicEmitter.GetClip() == musicToPlay) return; + startTime = _musicEmitter.FadeMusicOut(); } - if (_playingMusicAudioEmitter == null) - { - // TODO: Get new audio - } + if (!_musicEmitter) _musicEmitter = _emitter; + _musicEmitter.FadeMusicIn(currentClip, startTime); _currentBgmCue = audioToPlay; Debug.Log($"[AudioManager::HandleMusicToPlay] Playing background music: {audioToPlay.name}"); - }); + } + + AudioHelper.TryToLoadData(audioToPlay, OnAudioClipLoaded); } @@ -67,11 +71,11 @@ private void HandleMusicToStop() { if (!IsAudioPlaying()) return; - _playingMusicAudioEmitter.Stop(); + _musicEmitter.Stop(); Debug.Log($"[AudioManager] Stopped playing background music"); } - private bool IsAudioPlaying() => _playingMusicAudioEmitter != null && _playingMusicAudioEmitter.IsPlaying(); + private bool IsAudioPlaying() => _musicEmitter != null && _musicEmitter.IsPlaying(); } } \ No newline at end of file diff --git a/Assets/Scripts/System/Audio/Emitters/AudioEmitter.cs b/Assets/Scripts/System/Audio/Emitters/AudioEmitter.cs index b2ee62c..1b3dbc6 100644 --- a/Assets/Scripts/System/Audio/Emitters/AudioEmitter.cs +++ b/Assets/Scripts/System/Audio/Emitters/AudioEmitter.cs @@ -1,16 +1,92 @@ +using System.Collections; using UnityEngine; +using UnityEngine.Events; namespace Long18.System.Audio.Emitters { [RequireComponent((typeof(AudioSource)))] public class AudioEmitter : MonoBehaviour { + public event UnityAction OnFinishedPlaying; + private const float DEFAULT_VOLUME = 3f; + private const float FADE_VOLUME_DURATION = 2f; + [SerializeField] private AudioSource _audioSource; + private AudioEmitterValue _emitterValue; + + public void PlayAudioClip(AudioClip clip, bool hasLoop) + { + _emitterValue = new AudioEmitterValue(this); + + _audioSource.clip = clip; + // TODO: Create volume config + _audioSource.volume = DEFAULT_VOLUME; + _audioSource.loop = hasLoop; + _audioSource.time = 0f; + _audioSource.Play(); + + if (hasLoop) return; + Invoke(nameof(OnFinishedPlay), clip.length); + } + + public void FadeMusicIn(AudioClip clip, float startTime = 0f) + { + PlayAudioClip(clip, true); + StartCoroutine(FadeIn(0, 0.5f)); + + if (startTime <= _audioSource.clip.length) + { + _audioSource.time = startTime; + } + + // TODO: Create volume config + StartCoroutine(FadeIn(DEFAULT_VOLUME, FADE_VOLUME_DURATION)); + } + + public float FadeMusicOut() + { + StartCoroutine(FadeOut(FADE_VOLUME_DURATION)); + + return _audioSource.time; + } + + private IEnumerator FadeIn(float targetVolume, float duration) + { + float currentTime = 0; + float startVolume = _audioSource.volume; + + while (currentTime < duration) + { + currentTime += Time.deltaTime; + _audioSource.volume = Mathf.Lerp(startVolume, targetVolume, currentTime / duration); + yield return null; + } + + _audioSource.volume = targetVolume; + } + + private IEnumerator FadeOut(float duration) + { + float currentTime = 0; + float startVolume = _audioSource.volume; + + while (currentTime < duration) + { + currentTime += Time.deltaTime; + _audioSource.volume = Mathf.Lerp(startVolume, 0f, currentTime / duration); + yield return null; + } + + _audioSource.volume = 0f; + OnFinishedPlay(); + } + public void Resume() => _audioSource.Play(); public void Pause() => _audioSource.Pause(); public void Stop() => _audioSource.Stop(); public AudioClip GetClip() => _audioSource.clip; public bool IsPlaying() => _audioSource.isPlaying; + private void OnFinishedPlay() => OnFinishedPlaying?.Invoke(_emitterValue); } } \ No newline at end of file diff --git a/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs b/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs new file mode 100644 index 0000000..3f897df --- /dev/null +++ b/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs @@ -0,0 +1,22 @@ +using System; +using UnityEngine.Events; + +namespace Long18.System.Audio.Emitters +{ + [Serializable] + public struct AudioEmitterValue + { + private AudioEmitter _audioEmitter; + public AudioEmitterValue(AudioEmitter audioEmitter) => _audioEmitter = audioEmitter; + + public void UnregisterAudioFinishedPlayingEvent(UnityAction audioFinishedPlaying) + { + if (_audioEmitter) _audioEmitter.OnFinishedPlaying -= audioFinishedPlaying; + } + + public void StopAudio() + { + if (_audioEmitter) _audioEmitter.Stop(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs.meta b/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs.meta new file mode 100644 index 0000000..7d270dd --- /dev/null +++ b/Assets/Scripts/System/Audio/Emitters/AudioEmitterValue.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 05b419db24fa465cb865ca290861e2cd +timeCreated: 1706022674 \ No newline at end of file