diff --git a/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs b/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs new file mode 100644 index 0000000..173234e --- /dev/null +++ b/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs @@ -0,0 +1,23 @@ +namespace Code.Audio +{ + public enum SFXSounds + { + Crowbar, + Shot357 + } + public enum UISounds + { + Crowbar + } + public enum EnemiesSounds + { + Bastard, + Bravo + } + public enum DispatcherSounds + { + Absolutely, + AbsolutelyNot, + AhFreeman + } +} \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs.meta b/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs.meta new file mode 100644 index 0000000..69b17b7 --- /dev/null +++ b/Game/CourierOld/Assets/Code/Audio/AudioEnums.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 907b506ceac843ebb509a8e5298af540 +timeCreated: 1762888870 \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/AudioFactory.cs b/Game/CourierOld/Assets/Code/Audio/AudioFactory.cs index f4a7b8a..5605b43 100644 --- a/Game/CourierOld/Assets/Code/Audio/AudioFactory.cs +++ b/Game/CourierOld/Assets/Code/Audio/AudioFactory.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; using Code.Configs; using Cysharp.Threading.Tasks; +using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Audio; +using UnityEngine.ResourceManagement.AsyncOperations; using Object = UnityEngine.Object; namespace Code.Audio @@ -10,13 +13,29 @@ namespace Code.Audio public class AudioFactory : IAudioFactory { private AssetReference _audioMixerPrefab; + private AssetReference _audioSourcePrefab; private AssetReference[] _peacefulSoundtrack; private AssetReference[] _actionSoundtrack; + private AssetReference[] _menuSoundtrack; private AssetReference[] _SFX; private AssetReference[] _enemies; private AssetReference[] _dispatcher; private AssetReference[] _character; + + private AsyncOperationHandle> _menuMusicHandle; + private AsyncOperationHandle> _actionMusicHandle; + private AsyncOperationHandle> _peacefulMusicHandle; + private AsyncOperationHandle> _SFXHandle; + private AsyncOperationHandle> _enemiesHandle; + private AsyncOperationHandle> _dispatcherHandle; + + public List PeacefulMusic { get; private set; } + public List ActionMusic { get; private set; } + public List MenuMusic { get; private set; } + public List SFXAudios { get; private set; } + public List EnemiesAudios { get; private set; } + public List DispatcherAudios { get; private set; } public AudioFactory(AudioMixerConfig audioMixerConfig, SoundtrackListConfig soundtrackListConfig, @@ -26,15 +45,18 @@ namespace Code.Audio CharacterSoundListConfig characterSoundListConfig) { _audioMixerPrefab = audioMixerConfig.audioMixerPrefab; + _audioSourcePrefab = audioMixerConfig.audioSourcePrefab; _peacefulSoundtrack = soundtrackListConfig.peacefulSoundtrack; _actionSoundtrack = soundtrackListConfig.actionSoundtrack; + _actionSoundtrack = soundtrackListConfig.menuSoundtrack; _SFX = sfxListConfig.SFX; _enemies = enemiesSoundListConfig.enemies; _dispatcher = dispatcherSoundListConfig.dispatcher; _character = characterSoundListConfig.character; } - public async UniTask CreateCanvas() + + public async UniTask CreateMixer() { AudioMixer audioMixer = (await Addressables.InstantiateAsync(_audioMixerPrefab).ToUniTask()).GetComponent(); @@ -43,10 +65,108 @@ namespace Code.Audio return audioMixer; } - public void ReleaseMixer() + public async UniTaskVoid LoadAudioSourcePrefab(Action callback) => callback?.Invoke(await Addressables.LoadAssetAsync(_audioSourcePrefab)); + + public async UniTaskVoid WarmGameplayMusic(Action callback) { + _actionMusicHandle = Addressables.LoadAssetsAsync(_actionSoundtrack, OnActionTrackLoaded); + _peacefulMusicHandle = Addressables.LoadAssetsAsync(_peacefulSoundtrack, OnPeacefulTrackLoaded); + await UniTask.WhenAll(_actionMusicHandle.ToUniTask(), _peacefulMusicHandle.ToUniTask()); + + callback?.Invoke(); + } + + public void ReleaseGameplayMusic() + { + ActionMusic.Clear(); + _actionMusicHandle.Release(); + + PeacefulMusic.Clear(); + _peacefulMusicHandle.Release(); + } + + public async UniTaskVoid WarmMenuMusic(Action callback) + { + _menuMusicHandle = Addressables.LoadAssetsAsync(_menuSoundtrack, OnMenuTrackLoaded); + + await _menuMusicHandle.ToUniTask(); + + callback?.Invoke(); } + public void ReleaseMenuMusic() + { + MenuMusic.Clear(); + _menuMusicHandle.Release(); + } + public async UniTaskVoid WarmSFX(Action callback) + { + _SFXHandle = Addressables.LoadAssetsAsync(_SFX, OnSFXLoaded); + + await _SFXHandle.ToUniTask(); + + callback?.Invoke(); + } + + public void ReleaseSFX() + { + SFXAudios.Clear(); + _SFXHandle.Release(); + } + public async UniTaskVoid WarmEnemies(Action callback) + { + _enemiesHandle = Addressables.LoadAssetsAsync(_enemies, OnEnemiesLoaded); + + await _enemiesHandle.ToUniTask(); + + callback?.Invoke(); + } + + public void ReleaseEnemies() + { + EnemiesAudios.Clear(); + _enemiesHandle.Release(); + } + + public async UniTaskVoid WarmDispatcher(Action callback) + { + _dispatcherHandle = Addressables.LoadAssetsAsync(_dispatcher, OnDispatcherLoaded); + + await _dispatcherHandle.ToUniTask(); + + callback?.Invoke(); + } + + public void ReleaseDispatcher() + { + DispatcherAudios.Clear(); + _dispatcherHandle.Release(); + } + + private void OnActionTrackLoaded(AudioClip audioClip) + { + ActionMusic.Add(audioClip); + } + private void OnPeacefulTrackLoaded(AudioClip audioClip) + { + PeacefulMusic.Add(audioClip); + } + private void OnMenuTrackLoaded(AudioClip audioClip) + { + MenuMusic.Add(audioClip); + } + private void OnSFXLoaded(AudioClip audioClip) + { + SFXAudios.Add(audioClip); + } + private void OnEnemiesLoaded(AudioClip audioClip) + { + EnemiesAudios.Add(audioClip); + } + private void OnDispatcherLoaded(AudioClip audioClip) + { + DispatcherAudios.Add(audioClip); + } } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/AudioService.cs b/Game/CourierOld/Assets/Code/Audio/AudioService.cs index e28e1d1..d8a7a9b 100644 --- a/Game/CourierOld/Assets/Code/Audio/AudioService.cs +++ b/Game/CourierOld/Assets/Code/Audio/AudioService.cs @@ -1,17 +1,22 @@ using System; +using System.Collections.Generic; using Code.Configs; using Code.Constants; using Unity.VisualScripting; +using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Audio; +using Random = UnityEngine.Random; namespace Code.Audio { - public class AudioService : IAudioService, IDisposable + public class AudioService : IAudioService { private IAudioFactory _audioFactory; private AudioMixer _mixer; + private AudioSource _actionMusicSource; + private AudioSource _peacefulMusicSource; private AudioMixerGroup _masterGroup, _musicGroup, @@ -23,6 +28,10 @@ namespace Code.Audio _courierGroup, _enemiesGroup; + private readonly AudioSourcePool _audioSourcePool = new(); + + private Dictionary _snapshots = new(); + public AudioService(AudioFactory audioFactory) { _audioFactory = audioFactory; @@ -30,7 +39,7 @@ namespace Code.Audio public async void Initialize(Action callback) { - _mixer = await _audioFactory.CreateCanvas(); + _mixer = await _audioFactory.CreateMixer(); MixerCreated(); @@ -48,10 +57,53 @@ namespace Code.Audio _dispatcherGroup = _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0]; _courierGroup = _mixer.FindMatchingGroups(AudioGroups.CourierMusicGroup)[0]; _enemiesGroup = _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0]; + + _snapshots[AudioSnapshotState.Peaceful] = _mixer.FindSnapshot(AudioGroups.PeacefulSnapshot); + _snapshots[AudioSnapshotState.Action] = _mixer.FindSnapshot(AudioGroups.ActionSnapshot); + + _audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize); + + InitializeMusicSources(); } - public void Dispose() + private void InitializeMusicSources() { + _actionMusicSource = _audioSourcePool.GetSource(); + _actionMusicSource.outputAudioMixerGroup = _actionMusicGroup; + _actionMusicSource.spatialBlend = 0f; + + _peacefulMusicSource = _audioSourcePool.GetSource(); + _peacefulMusicSource.outputAudioMixerGroup = _peacefulMusicGroup; + _peacefulMusicSource.spatialBlend = 0f; + } + + public void PlayRandomGameplayMusic() + { + _peacefulMusicSource.resource = _audioFactory.PeacefulMusic[Random.Range(0, _audioFactory.PeacefulMusic.Count)]; + _actionMusicSource.resource = + _audioFactory.ActionMusic[Random.Range(0, _audioFactory.ActionMusic.Count)]; + + _peacefulMusicSource.Play(); + _actionMusicSource.Play(); + } + + public void TransitToSnapshot(AudioSnapshotState state) + { + _snapshots[state].TransitionTo(1f); + } + +#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed + public void PlaySFX(SFXSounds sfxId, Vector3 position) + { + _audioSourcePool.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _SFXGroup); + } + public void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position) + { + _audioSourcePool.PlayOneShot(_audioFactory.EnemiesAudios[(int)enemySoundId], position, _enemiesGroup); + } + public void PlayDispatcher(DispatcherSounds dispatcherSoundId) + { + _audioSourcePool.PlayShizo(_audioFactory.DispatcherAudios[(int)dispatcherSoundId], _dispatcherGroup); } } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/AudioServiceDebug.cs b/Game/CourierOld/Assets/Code/Audio/AudioServiceDebug.cs index 5c02c07..3add90c 100644 --- a/Game/CourierOld/Assets/Code/Audio/AudioServiceDebug.cs +++ b/Game/CourierOld/Assets/Code/Audio/AudioServiceDebug.cs @@ -50,7 +50,7 @@ namespace Code.Audio _snapshots[AudioSnapshotState.Peaceful] = mixer.FindSnapshot(AudioGroups.PeacefulSnapshot); _snapshots[AudioSnapshotState.Action] = mixer.FindSnapshot(AudioGroups.ActionSnapshot); - _audioSourcePool.Initialize(10,prefab); + // _audioSourcePool.Initialize(10,prefab); InitializeMusicSources(); } @@ -114,26 +114,6 @@ namespace Code.Audio #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } - public enum SFXSounds - { - Crowbar, - Shot357 - } - public enum UISounds - { - Crowbar - } - public enum EnemiesSounds - { - Bastard, - Bravo - } - public enum DispatcherSounds - { - Absolutely, - AbsolutelyNot, - AhFreeman - } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/AudioSourcePool.cs b/Game/CourierOld/Assets/Code/Audio/AudioSourcePool.cs index 4054c15..d857e0f 100644 --- a/Game/CourierOld/Assets/Code/Audio/AudioSourcePool.cs +++ b/Game/CourierOld/Assets/Code/Audio/AudioSourcePool.cs @@ -11,7 +11,7 @@ namespace Code.Audio private IObjectPool _pool; private AudioSource _sourcePrefab; - public void Initialize(int count, AudioSource sourcePrefab) + public void Initialize(AudioSource sourcePrefab) { _sourcePrefab = sourcePrefab; @@ -22,7 +22,7 @@ namespace Code.Audio // actionOnRelease: OnRelease, actionOnDestroy: OnDestroyItem, collectionCheck: true, // helps catch double-release mistakes - defaultCapacity: count, + defaultCapacity: 10, maxSize: 20 ); } diff --git a/Game/CourierOld/Assets/Code/Audio/IAudioFactory.cs b/Game/CourierOld/Assets/Code/Audio/IAudioFactory.cs index ec215be..fe52930 100644 --- a/Game/CourierOld/Assets/Code/Audio/IAudioFactory.cs +++ b/Game/CourierOld/Assets/Code/Audio/IAudioFactory.cs @@ -1,10 +1,30 @@ +using System; +using System.Collections.Generic; using Cysharp.Threading.Tasks; +using UnityEngine; using UnityEngine.Audio; namespace Code.Audio { public interface IAudioFactory { - UniTask CreateCanvas(); + List PeacefulMusic { get; } + List ActionMusic { get; } + List MenuMusic { get; } + List SFXAudios { get; } + List EnemiesAudios { get; } + List DispatcherAudios { get; } + UniTask CreateMixer(); + UniTaskVoid LoadAudioSourcePrefab(Action callback); + UniTaskVoid WarmGameplayMusic(Action callback); + void ReleaseGameplayMusic(); + UniTaskVoid WarmMenuMusic(Action callback); + void ReleaseMenuMusic(); + UniTaskVoid WarmSFX(Action callback); + void ReleaseSFX(); + UniTaskVoid WarmEnemies(Action callback); + void ReleaseEnemies(); + UniTaskVoid WarmDispatcher(Action callback); + void ReleaseDispatcher(); } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Audio/IAudioService.cs b/Game/CourierOld/Assets/Code/Audio/IAudioService.cs index 6ba926c..67a9bfe 100644 --- a/Game/CourierOld/Assets/Code/Audio/IAudioService.cs +++ b/Game/CourierOld/Assets/Code/Audio/IAudioService.cs @@ -1,9 +1,15 @@ using System; +using UnityEngine; namespace Code.Audio { public interface IAudioService { void Initialize(Action callback); + void PlayRandomGameplayMusic(); + void TransitToSnapshot(AudioSnapshotState state); + void PlaySFX(SFXSounds sfxId, Vector3 position); + void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position); + void PlayDispatcher(DispatcherSounds dispatcherSoundId); } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Configs/AudioMixerConfig.cs b/Game/CourierOld/Assets/Code/Configs/AudioMixerConfig.cs index f0eb3f7..70bc016 100644 --- a/Game/CourierOld/Assets/Code/Configs/AudioMixerConfig.cs +++ b/Game/CourierOld/Assets/Code/Configs/AudioMixerConfig.cs @@ -7,5 +7,6 @@ namespace Code.Configs public class AudioMixerConfig : ScriptableObject { public AssetReference audioMixerPrefab; + public AssetReference audioSourcePrefab; } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Configs/SoundtrackListConfig.cs b/Game/CourierOld/Assets/Code/Configs/SoundtrackListConfig.cs index ecec6d3..84be161 100644 --- a/Game/CourierOld/Assets/Code/Configs/SoundtrackListConfig.cs +++ b/Game/CourierOld/Assets/Code/Configs/SoundtrackListConfig.cs @@ -7,6 +7,7 @@ namespace Code.Configs public class SoundtrackListConfig : ScriptableObject { public AssetReference[] peacefulSoundtrack; - public AssetReference[] actionSoundtrack; + public AssetReference[] actionSoundtrack; + public AssetReference[] menuSoundtrack; } } \ No newline at end of file