Now Audio Playing
This commit is contained in:
1 parent
b7527d8d68
commit
513d6d0bc5
62 files changed
+1168
-119
No files matched your search
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Code.Infrastructure.Configs;
|
||||
using Code.Infrastructure.EventBus;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.Audio;
|
||||
using UnityEngine.Pool;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Code.Infrastructure.Audio
|
||||
{
|
||||
public interface IAudioSourcePool
|
||||
{
|
||||
AudioSource GetSource(AudioSourceType sourceType);
|
||||
void ReleaseSource(AudioSource source);
|
||||
}
|
||||
|
||||
public class AudioSourcePool : IAudioSourcePool, IDisposable
|
||||
{
|
||||
// The pool holds plain GameObjects (you can swap this for any component type).
|
||||
private IObjectPool<AudioSource> _pool;
|
||||
private GameObject _sourcePrefab;
|
||||
|
||||
private Dictionary<AudioSourceType, AudioSourceSettingsConfig> _settings;
|
||||
|
||||
public AudioSourcePool(Dictionary<AudioSourceType, AudioSourceSettingsConfig> settings) => _settings = settings;
|
||||
|
||||
private string _configsLabel;
|
||||
private AsyncOperationHandle<IList<AudioSourceSettingsConfig>> _handles;
|
||||
private AssetReference _sourcePrefabConfigReference;
|
||||
private AsyncOperationHandle<AudioSourcePrefabConfig> _prefabConfigHandle;
|
||||
private AsyncOperationHandle<GameObject> _prefabHandle;
|
||||
private EventBus.EventBus _eventBus;
|
||||
|
||||
public AudioSourcePool(IConfigLocator configLocator, EventBus.EventBus eventBus)
|
||||
{
|
||||
_eventBus = eventBus;
|
||||
|
||||
_configsLabel = configLocator.TryGetManyConfigAssetReferences<AudioSourceSettingsConfig>();
|
||||
_sourcePrefabConfigReference = configLocator.TryGetConfigAssetReference<AudioSourcePrefabConfig>();
|
||||
|
||||
LoadConfigs().Forget();
|
||||
}
|
||||
|
||||
private async UniTaskVoid LoadConfigs()
|
||||
{
|
||||
_prefabConfigHandle = Addressables.LoadAssetAsync<AudioSourcePrefabConfig>(_sourcePrefabConfigReference);
|
||||
_handles = Addressables.LoadAssetsAsync<AudioSourceSettingsConfig>(_configsLabel);
|
||||
|
||||
await UniTask.WhenAll(
|
||||
_prefabConfigHandle.ToUniTask(),
|
||||
_handles.ToUniTask());
|
||||
|
||||
_prefabHandle = Addressables.LoadAssetAsync<GameObject>(_prefabConfigHandle.Result.prefabReference);
|
||||
|
||||
_settings = _handles.Result.ToDictionary(x => x.sourceType);
|
||||
|
||||
await _prefabHandle.ToUniTask();
|
||||
|
||||
_pool = new ObjectPool<AudioSource>(
|
||||
createFunc: CreateItem,
|
||||
// actionOnGet: OnGet,
|
||||
actionOnRelease: OnRelease,
|
||||
actionOnDestroy: OnDestroyItem,
|
||||
collectionCheck: true, // helps catch double-release mistakes
|
||||
defaultCapacity: 10,
|
||||
maxSize: 20
|
||||
);
|
||||
|
||||
_eventBus.RaiseEvent<IAudioSourcePoolInitializedHandle>(x => x.AudioSourcePoolInitialized());
|
||||
}
|
||||
// Creates a new pooled GameObject the first time (and whenever the pool needs more).
|
||||
private AudioSource CreateItem()
|
||||
{
|
||||
var audioSource = Object.Instantiate(_prefabHandle.Result).GetComponent<AudioSource>();
|
||||
audioSource.name = "PooledAudioSource";
|
||||
Object.DontDestroyOnLoad(audioSource);
|
||||
return audioSource;
|
||||
}
|
||||
|
||||
// Called when an item is taken from the pool.
|
||||
private void OnGet(AudioSource source)
|
||||
{
|
||||
//source.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
// Called when an item is returned to the pool.
|
||||
private void OnRelease(AudioSource source)
|
||||
{
|
||||
source.Stop();
|
||||
//source.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Called when the pool decides to destroy an item (e.g., above max size).
|
||||
private void OnDestroyItem(AudioSource source)
|
||||
{
|
||||
Object.Destroy(source.gameObject);
|
||||
}
|
||||
//
|
||||
// public async UniTaskVoid PlayOneShot(AudioClip clip, Vector3 position, AudioMixerGroup audioMixerGroup, AudioSourceType audioSourceType = AudioSourceType.NoBlend, Action onComplete = null)
|
||||
// {
|
||||
// AudioSource source = _pool.Get();
|
||||
// source.PlayOneShot(clip);
|
||||
// source.spatialBlend = _settings[audioSourceType].spatialBlend;
|
||||
// source.transform.position = position;
|
||||
// source.outputAudioMixerGroup = audioMixerGroup;
|
||||
//
|
||||
// await UniTask.WaitUntilValueChanged(source, x => x.isPlaying);
|
||||
// onComplete?.Invoke();
|
||||
// _pool.Release(source);
|
||||
// }
|
||||
// public async UniTaskVoid PlayOneShot(AudioClip clip, AudioMixerGroup audioMixerGroup, AudioSourceType audioSourceType = AudioSourceType.NoBlend, Action onComplete = null)
|
||||
// {
|
||||
// AudioSource source = _pool.Get();
|
||||
// source.PlayOneShot(clip);
|
||||
// source.spatialBlend = _settings[audioSourceType].spatialBlend;
|
||||
// source.outputAudioMixerGroup = audioMixerGroup;
|
||||
//
|
||||
// await UniTask.WaitUntilValueChanged(source, x => x.isPlaying);
|
||||
// onComplete?.Invoke();
|
||||
// _pool.Release(source);
|
||||
// }
|
||||
// public async UniTaskVoid PlayOneShot(AudioSource audioSource, AudioClip clip, AudioMixerGroup audioMixerGroup, AudioSourceType audioSourceType = AudioSourceType.NoBlend, Action onComplete = null)
|
||||
// {
|
||||
// audioSource.PlayOneShot(clip);
|
||||
// audioSource.spatialBlend = _settings[audioSourceType].spatialBlend;
|
||||
// audioSource.outputAudioMixerGroup = audioMixerGroup;
|
||||
//
|
||||
// // TODO Потом сделать. Можно с cancellation, но сейчас лень. Ну правда
|
||||
// await UniTask.WaitUntilValueChanged(audioSource, x => x.isPlaying);
|
||||
//
|
||||
// if (!audioSource) return;
|
||||
//
|
||||
// _pool.Release(audioSource);
|
||||
// onComplete?.Invoke();
|
||||
// }
|
||||
// public async UniTaskVoid PlayOneShot(AudioClip clip, AudioMixerGroup audioMixerGroup, CancellationTokenSource cancellationToken, AudioSourceType audioSourceType = AudioSourceType.NoBlend, Action onComplete = null)
|
||||
// {
|
||||
// AudioSource source = _pool.Get();
|
||||
// source.PlayOneShot(clip);
|
||||
// source.spatialBlend = _settings[audioSourceType].spatialBlend;
|
||||
// source.outputAudioMixerGroup = audioMixerGroup;
|
||||
//
|
||||
// var (isCanceled, _) = await UniTask.WaitUntilValueChanged(source, x => x.isPlaying, cancellationToken: cancellationToken.Token).SuppressCancellationThrow();
|
||||
//
|
||||
// _pool.Release(source);
|
||||
//
|
||||
// if(!isCanceled) onComplete?.Invoke();
|
||||
// else cancellationToken.Dispose();
|
||||
// }
|
||||
public AudioSource GetSource(AudioSourceType sourceType)
|
||||
{
|
||||
var source = _pool.Get();
|
||||
|
||||
source.spatialBlend = _settings[sourceType].spatialBlend;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
public void ReleaseSource(AudioSource source) => _pool.Release(source);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Addressables.Release(_handles);
|
||||
Addressables.Release(_prefabConfigHandle);
|
||||
Addressables.Release(_sourcePrefab);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IAudioSourcePoolInitializedHandle : IGlobalSubscriber
|
||||
{
|
||||
void AudioSourcePoolInitialized();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user