Музыка есть

This commit is contained in:
ThomasCharester committed 2025-11-13 23:13:41 +03:00
1 parent 557c4c3dee
commit 346dc97fef
67 files changed
+774 -66

No files matched your search

@@ -12,7 +12,7 @@ namespace Code.Audio
{
public class AudioFactory : IAudioFactory
{
private AssetReference _audioMixerPrefab;
public AudioMixer AudioMixer { get; private set; }
private AssetReference _audioSourcePrefab;
private AssetReference[] _peacefulSoundtrack;
@@ -29,43 +29,42 @@ namespace Code.Audio
private AsyncOperationHandle<IList<AudioClip>> _SFXHandle;
private AsyncOperationHandle<IList<AudioClip>> _enemiesHandle;
private AsyncOperationHandle<IList<AudioClip>> _dispatcherHandle;
public List<AudioClip> PeacefulMusic { get; private set; }
public List<AudioClip> ActionMusic { get; private set; }
public List<AudioClip> MenuMusic { get; private set; }
public List<AudioClip> SFXAudios { get; private set; }
public List<AudioClip> EnemiesAudios { get; private set; }
public List<AudioClip> DispatcherAudios { get; private set; }
public List<AudioClip> PeacefulMusic { get; private set; } = new();
public List<AudioClip> ActionMusic { get; private set; } = new();
public List<AudioClip> MenuMusic { get; private set; } = new();
public List<AudioClip> SFXAudios { get; private set; } = new();
public List<AudioClip> EnemiesAudios { get; private set; } = new();
public List<AudioClip> DispatcherAudios { get; private set; } = new();
public AudioFactory(AudioMixerConfig audioMixerConfig,
SoundtrackListConfig soundtrackListConfig,
SFXListConfig sfxListConfig,
EnemiesSoundListConfig enemiesSoundListConfig,
DispatcherSoundListConfig dispatcherSoundListConfig,
CharacterSoundListConfig characterSoundListConfig)
DispatcherSoundListConfig dispatcherSoundListConfig//, CharacterSoundListConfig characterSoundListConfig
)
{
_audioMixerPrefab = audioMixerConfig.audioMixerPrefab;
AudioMixer = audioMixerConfig.audioMixerAsset;
_audioSourcePrefab = audioMixerConfig.audioSourcePrefab;
_peacefulSoundtrack = soundtrackListConfig.peacefulSoundtrack;
_actionSoundtrack = soundtrackListConfig.actionSoundtrack;
_actionSoundtrack = soundtrackListConfig.menuSoundtrack;
_menuSoundtrack = soundtrackListConfig.menuSoundtrack;
_SFX = sfxListConfig.SFX;
_enemies = enemiesSoundListConfig.enemies;
_dispatcher = dispatcherSoundListConfig.dispatcher;
_character = characterSoundListConfig.character;
// _character = characterSoundListConfig.character;
}
public async UniTask<AudioMixer> CreateMixer()
{
AudioMixer audioMixer = (await Addressables.InstantiateAsync(_audioMixerPrefab).ToUniTask()).GetComponent<AudioMixer>();
Object.DontDestroyOnLoad(audioMixer);
return audioMixer;
}
// public async UniTask<AudioMixer> CreateMixer()
// {
// AudioMixer audioMixer = (await Addressables.InstantiateAsync(_audioMixerPrefab).ToUniTask()).GetComponent<AudioMixer>();
//
// return audioMixer;
// }
public async UniTaskVoid LoadAudioSourcePrefab(Action<AudioSource> callback) => callback?.Invoke(await Addressables.LoadAssetAsync<AudioSource>(_audioSourcePrefab));
public async UniTask LoadAudioSourcePrefab(Action<GameObject> callback) =>
callback?.Invoke(await Addressables.LoadAssetAsync<GameObject>(_audioSourcePrefab));
public async UniTaskVoid WarmGameplayMusic(Action callback)
{
@@ -88,8 +87,8 @@ namespace Code.Audio
public async UniTaskVoid WarmMenuMusic(Action callback)
{
_menuMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_menuSoundtrack, OnMenuTrackLoaded);
_menuMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_menuSoundtrack, OnMenuTrackLoaded, Addressables.MergeMode.None);
// foreach (var assetReference in _menuSoundtrack) MenuMusic.Add(await assetReference.LoadAssetAsync<AudioClip>());
await _menuMusicHandle.ToUniTask();
callback?.Invoke();
@@ -98,6 +97,7 @@ namespace Code.Audio
public void ReleaseMenuMusic()
{
MenuMusic.Clear();
// foreach (var assetReference in _menuSoundtrack) assetReference.ReleaseAsset();
_menuMusicHandle.Release();
}
public async UniTaskVoid WarmSFX(Action callback)
+132 -14
View File
@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Code.Configs;
using Code.Constants;
using Cysharp.Threading.Tasks;
using Reflex.Attributes;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AddressableAssets;
@@ -32,22 +35,16 @@ namespace Code.Audio
private Dictionary<AudioSnapshotState, AudioMixerSnapshot> _snapshots = new();
public AudioService(AudioFactory audioFactory)
public AudioService(IAudioFactory audioFactory)
{
_audioFactory = audioFactory;
}
public async void Initialize(Action callback)
public async UniTaskVoid Initialize(Action callback)
{
_mixer = await _audioFactory.CreateMixer();
// _mixer = await _audioFactory.CreateMixer();
_mixer = _audioFactory.AudioMixer;
MixerCreated();
callback?.Invoke();
}
private void MixerCreated()
{
_masterGroup = _mixer.FindMatchingGroups(AudioGroups.MasterGroup)[0];
_actionMusicGroup = _mixer.FindMatchingGroups(AudioGroups.ActionMusicGroup)[0];
_peacefulMusicGroup = _mixer.FindMatchingGroups(AudioGroups.PeacefulMusicGroup)[0];
@@ -60,10 +57,13 @@ namespace Code.Audio
_snapshots[AudioSnapshotState.Peaceful] = _mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
_snapshots[AudioSnapshotState.Action] = _mixer.FindSnapshot(AudioGroups.ActionSnapshot);
_snapshots[AudioSnapshotState.None] = _mixer.FindSnapshot(AudioGroups.NoneSnapshot);
_audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize);
await _audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize);
InitializeMusicSources();
callback?.Invoke();
}
private void InitializeMusicSources()
@@ -86,10 +86,128 @@ namespace Code.Audio
_peacefulMusicSource.Play();
_actionMusicSource.Play();
}
public void TransitToSnapshot(AudioSnapshotState state)
public void PlayRandomMenuMusic()
{
_snapshots[state].TransitionTo(1f);
TransitToSnapshot(AudioSnapshotState.Peaceful);
_peacefulMusicSource.resource = _audioFactory.MenuMusic[Random.Range(0, _audioFactory.MenuMusic.Count)];
_peacefulMusicSource.Play();
}
private CancellationTokenSource _menuMusicTokenSource = new();
public async UniTaskVoid PlayRandomMenuMusicUntilHumanityWillBeDestroyedForTheySins()
{
TransitToSnapshot(AudioSnapshotState.Peaceful);
_peacefulMusicSource.resource = _audioFactory.MenuMusic[Random.Range(0, _audioFactory.MenuMusic.Count)];
_peacefulMusicSource.Play();
await UniTask.WaitUntilValueChanged(_peacefulMusicSource, _ => _peacefulMusicSource.isPlaying, cancellationToken: _menuMusicTokenSource.Token);
if (_menuMusicTokenSource.IsCancellationRequested)
{
_menuMusicTokenSource.Dispose();
_menuMusicTokenSource = new();
return;
}
PlayRandomMenuMusicUntilHumanityWillBeDestroyedForTheySins();
}
private CancellationTokenSource _peacefulMusicTokenSource = new();
public async UniTaskVoid PlayRandomPeacefulMusicUntilHumanityWillBeDestroyedForTheySins()
{
TransitToSnapshot(AudioSnapshotState.Peaceful);
_peacefulMusicSource.resource = _audioFactory.PeacefulMusic[Random.Range(0, _audioFactory.PeacefulMusic.Count)];
_peacefulMusicSource.Play();
await UniTask.WaitUntilValueChanged(_peacefulMusicSource, _ => _peacefulMusicSource.isPlaying, cancellationToken: _peacefulMusicTokenSource.Token);
if (_peacefulMusicTokenSource.IsCancellationRequested)
{
_peacefulMusicTokenSource.Dispose();
_peacefulMusicTokenSource = new();
return;
}
PlayRandomPeacefulMusicUntilHumanityWillBeDestroyedForTheySins();
}
private CancellationTokenSource _actionMusicTokenSource = new();
public async UniTaskVoid PlayRandomActionMusicUntilHumanityWillBeDestroyedForTheySins()
{
TransitToSnapshot(AudioSnapshotState.Action);
_actionMusicSource.resource = _audioFactory.ActionMusic[Random.Range(0, _audioFactory.ActionMusic.Count)];
_actionMusicSource.Play();
await UniTask.WaitUntilValueChanged(_actionMusicSource, _ => _actionMusicSource.isPlaying, cancellationToken: _actionMusicTokenSource.Token);
if (_actionMusicTokenSource.IsCancellationRequested)
{
_actionMusicTokenSource.Dispose();
_actionMusicTokenSource = new();
return;
}
PlayRandomActionMusicUntilHumanityWillBeDestroyedForTheySins();
}
public void StopMusic()
{
_peacefulMusicSource.Stop();
_actionMusicSource.Stop();
}
public void GladlyAskToStopMusic(Action callback = null)
{
TransitToSnapshot(AudioSnapshotState.None);
_peacefulMusicSource.Stop();
_actionMusicSource.Stop();
callback?.Invoke();
}
public async UniTaskVoid GladlyAskToStopMenuMusic(Action callback = null)
{
TransitToSnapshot(AudioSnapshotState.None);
await UniTask.WaitForSeconds(1f);
_peacefulMusicSource.Stop();
_menuMusicTokenSource.Cancel();
callback?.Invoke();
}
public async UniTaskVoid GladlyAskToStopActionMusic(Action callback = null)
{
TransitToSnapshot(AudioSnapshotState.None);
await UniTask.WaitForSeconds(1f);
_actionMusicSource.Stop();
_actionMusicTokenSource.Cancel();
callback?.Invoke();
}
public async UniTaskVoid GladlyAskToStopPeacefulMusic(Action callback = null)
{
TransitToSnapshot(AudioSnapshotState.None);
await UniTask.WaitForSeconds(1f);
_peacefulMusicSource.Stop();
_peacefulMusicTokenSource.Cancel();
callback?.Invoke();
}
public void TransitToSnapshot(AudioSnapshotState state, float time = 1f)
{
_snapshots[state].TransitionTo(time);
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -2,6 +2,7 @@ namespace Code.Audio
{
public enum AudioSnapshotState
{
None,
Peaceful,
Action
}
@@ -9,9 +9,9 @@ namespace Code.Audio
{
// The pool holds plain GameObjects (you can swap this for any component type).
private IObjectPool<AudioSource> _pool;
private AudioSource _sourcePrefab;
private GameObject _sourcePrefab;
public void Initialize(AudioSource sourcePrefab)
public void Initialize(GameObject sourcePrefab)
{
_sourcePrefab = sourcePrefab;
@@ -30,7 +30,7 @@ namespace Code.Audio
// Creates a new pooled GameObject the first time (and whenever the pool needs more).
private AudioSource CreateItem()
{
AudioSource audioSource = Object.Instantiate(_sourcePrefab);
AudioSource audioSource = Object.Instantiate(_sourcePrefab).GetComponent<AudioSource>();
audioSource.name = "PooledAudioSource";
Object.DontDestroyOnLoad(audioSource);
return audioSource;
@@ -14,8 +14,8 @@ namespace Code.Audio
List<AudioClip> SFXAudios { get; }
List<AudioClip> EnemiesAudios { get; }
List<AudioClip> DispatcherAudios { get; }
UniTask<AudioMixer> CreateMixer();
UniTaskVoid LoadAudioSourcePrefab(Action<AudioSource> callback);
AudioMixer AudioMixer { get; }
UniTask LoadAudioSourcePrefab(Action<GameObject> callback);
UniTaskVoid WarmGameplayMusic(Action callback);
void ReleaseGameplayMusic();
UniTaskVoid WarmMenuMusic(Action callback);
@@ -1,15 +1,23 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace Code.Audio
{
public interface IAudioService
{
void Initialize(Action callback);
UniTaskVoid Initialize(Action callback);
void PlayRandomGameplayMusic();
void TransitToSnapshot(AudioSnapshotState state);
void TransitToSnapshot(AudioSnapshotState state, float time = 1f);
void PlaySFX(SFXSounds sfxId, Vector3 position);
void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position);
void PlayDispatcher(DispatcherSounds dispatcherSoundId);
void PlayRandomMenuMusic();
UniTaskVoid PlayRandomMenuMusicUntilHumanityWillBeDestroyedForTheySins();
void StopMusic();
void GladlyAskToStopMusic(Action callback = null);
UniTaskVoid GladlyAskToStopMenuMusic(Action callback = null);
UniTaskVoid GladlyAskToStopActionMusic(Action callback = null);
UniTaskVoid GladlyAskToStopPeacefulMusic(Action callback = null);
}
}