using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.Configs; using Code.Infrastructure.EventBus; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Object = UnityEngine.Object; namespace Code.Infrastructure.Volume { public interface IVolumeFactory { UniTaskVoid LoadVolume(VolumeId volumeId, Transform transform = null); void ReleaseVolume(UnityEngine.Rendering.Volume volume); } public class VolumeFactory : IDisposable, IVolumeFactory { private EventBus.EventBus _eventBus; private Dictionary _configs; private AsyncOperationHandle> _configsHandle; private string _configsLabel; public VolumeFactory(IConfigLocator configLocator, EventBus.EventBus eventBus) { _eventBus = eventBus; _configsLabel = configLocator.TryGetManyConfigAssetReferences(); LoadConfigs().Forget(); } private async UniTaskVoid LoadConfigs() { _configsHandle = Addressables.LoadAssetsAsync(_configsLabel); await _configsHandle.ToUniTask(); _configs = _configsHandle.Result.ToDictionary(c => c.id); _eventBus.RaiseEvent(ui => ui.VolumesInitialized()); } public async UniTaskVoid LoadVolume(VolumeId volumeId, Transform transform = null) { UnityEngine.Rendering.Volume volume = transform == null ? (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); _eventBus.RaiseEvent(ui => ui.VolumeLoaded(volume, volumeId)); } public void ReleaseVolume(UnityEngine.Rendering.Volume volume) { Addressables.ReleaseInstance(volume.gameObject); } public void Dispose() { Addressables.Release(_configsHandle); } } internal interface IVolumesInitializedHandle : IGlobalSubscriber { void VolumesInitialized(); } internal interface IVolumeLoadedHandle : IGlobalSubscriber { void VolumeLoaded(UnityEngine.Rendering.Volume volume, VolumeId volumeId); } }