using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.Configs; using Code.Infrastructure.Utils; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Object = UnityEngine.Object; namespace Code.Infrastructure.Volume { public interface IVolumeFactory { UniTask LoadVolume(VolumeId volumeId, Transform transform = null); void ReleaseVolume(UnityEngine.Rendering.Volume volume); } public interface IVolumeFactoryInitializer { UniTask LoadConfigs(); } public class VolumeFactory : IDisposable, IVolumeFactory, IVolumeFactoryInitializer { private Dictionary _configs; private AsyncOperationHandle> _configsHandle; private string _configsLabel; public VolumeFactory(IConfigLocator configLocator) { _configsLabel = configLocator.TryGetManyConfigAssetReferences(); } public async UniTask LoadConfigs() { if(!await AddressablesUtilities.CheckLabelExists(_configsLabel)) { _configs = new(); return; } _configsHandle = Addressables.LoadAssetsAsync(_configsLabel); await _configsHandle.ToUniTask(); _configs = _configsHandle.Result.ToDictionary(c => c.id); } public async UniTask LoadVolume(VolumeId volumeId, Transform transform = null) { UnityEngine.Rendering.Volume volume = !transform ? (await Addressables.InstantiateAsync(_configs[volumeId].prefab, transform).ToUniTask()) .GetComponent() : (await Addressables.InstantiateAsync(_configs[volumeId].prefab).ToUniTask()) .GetComponent(); if(_configs[volumeId].doNotDestroyOnLoad) Object.DontDestroyOnLoad(volume.gameObject); return volume; } public void ReleaseVolume(UnityEngine.Rendering.Volume volume) { Addressables.ReleaseInstance(volume.gameObject); } public void Dispose() { if(_configsHandle.IsValid()) Addressables.Release(_configsHandle); } } }