using System; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Random = UnityEngine.Random; namespace Code.Infrastructure.Audio { [Serializable] public abstract class AudioReference { public abstract UniTask Load(); public abstract void Unload(); } [Serializable] public class AudioReferenceLODed : AudioReference { private AsyncOperationHandle _interiorClipHandle; private AsyncOperationHandle _closeClipHandle; private AsyncOperationHandle _distantClipHandle; private AsyncOperationHandle _farClipHandle; public override async UniTask Load() { if (_interiorClipHandle.IsValid()) return; _interiorClipHandle = Addressables.LoadAssetAsync(interior); _closeClipHandle = Addressables.LoadAssetAsync(close); _distantClipHandle = Addressables.LoadAssetAsync(distant); _farClipHandle = Addressables.LoadAssetAsync(far); await UniTask.WhenAll( _interiorClipHandle.ToUniTask(), _closeClipHandle.ToUniTask(), _distantClipHandle.ToUniTask(), _farClipHandle.ToUniTask() ); Interior = _interiorClipHandle.Result; Close = _closeClipHandle.Result; Distant = _distantClipHandle.Result; Far = _farClipHandle.Result; } public override void Unload() { if (!_interiorClipHandle.IsValid()) return; _interiorClipHandle.Release(); _closeClipHandle.Release(); _distantClipHandle.Release(); _farClipHandle.Release(); Interior = null; Close = null; Distant = null; Far = null; } [SerializeField] private AssetReference interior; [SerializeField] private AssetReference close; [SerializeField] private AssetReference distant; [SerializeField] private AssetReference far; public AudioClip Interior { get; private set; } public AudioClip Close { get; private set; } public AudioClip Distant { get; private set; } public AudioClip Far { get; private set; } } [Serializable] public class AudioReferenceSingle : AudioReference { private AsyncOperationHandle _clipHandle; public override async UniTask Load() { if (_clipHandle.IsValid()) return; _clipHandle = Addressables.LoadAssetAsync(clip); await _clipHandle.ToUniTask(); Clip = _clipHandle.Result; } public override void Unload() { if (!_clipHandle.IsValid()) return; _clipHandle.Release(); Clip = null; } [SerializeField] private AssetReference clip; public AudioClip Clip { get; private set; } } [Serializable] public class AudioReferenceRandom : AudioReference { private AsyncOperationHandle[] _clipHandles; public override async UniTask Load() { if (_clipHandles != null) return; _clipHandles = new AsyncOperationHandle[clips.Length]; for (var i = 0; i < clips.Length; i++) { _clipHandles[i] = Addressables.LoadAssetAsync(clips[i]); await _clipHandles[i].ToUniTask(); } } public override void Unload() { if (_clipHandles == null) return; for (var i = 0; i < clips.Length; i++) Addressables.Release(_clipHandles[i]); } [SerializeField] private AssetReference[] clips; public AudioClip Clip => _clipHandles[Random.Range(0, _clipHandles.Length)].Result; } }