using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.Configs; using Code.Infrastructure.Utils; using Cysharp.Threading.Tasks; using Unity.VisualScripting; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; namespace Code.Infrastructure.UI { public interface IUIFactory { // Новый Canvas GameplayCanvas { get; } // Тот что был создан на сцене Canvas Canvas { get; } UniTask LoadPanel(UIPanelType panelType, bool gameplayCanvas, Transform parent = null); } public interface IUIFactoryInitializer { UniTask LoadConfigs(); void SetCanvas(Canvas canvas); void SetCanvasCamera(UnityEngine.Camera camera); } public class UIFactory : IDisposable, IUIFactory, IUIFactoryInitializer { private Dictionary _configs; private readonly AssetReference _canvasConfigReference; private readonly string _configsLabel; private AsyncOperationHandle> _configsHandle; private AsyncOperationHandle _canvasSettingsHandle; private CanvasSettings _canvasConfig; private GameObject _gameplayCanvas; public Canvas GameplayCanvas { get; private set; } public Canvas Canvas { get; private set; } public UIFactory(IConfigLocator configLocator) { _configsLabel = configLocator.TryGetManyConfigAssetReferences(); _canvasConfigReference = configLocator.TryGetConfigAssetReference(); } public void SetCanvas(Canvas canvas) { Canvas = canvas; UnityEngine.Object.DontDestroyOnLoad(canvas.gameObject); } public void SetCanvasCamera(UnityEngine.Camera camera) { Canvas.worldCamera = camera; Canvas.planeDistance = 0.1f; GameplayCanvas.worldCamera = camera; } public async UniTask LoadPanel(UIPanelType panelType, bool gameplayCanvas, Transform parent = null) { var panel = (await Addressables.InstantiateAsync(_configs[panelType].Prefab, parent ?? gameplayCanvas ? _gameplayCanvas.transform : Canvas.transform).ToUniTask()) .GetComponent(); panel.PanelType = panelType; return panel; } public async UniTask LoadConfigs() { if (await AddressablesUtilities.CheckLabelExists(_configsLabel)) await LoadPanelConfigs(); _canvasSettingsHandle = Addressables.LoadAssetAsync(_canvasConfigReference); await _canvasSettingsHandle.ToUniTask(); _canvasConfig = _canvasSettingsHandle.Result; _gameplayCanvas = new GameObject { name = "GameplayCanvas" }; UnityEngine.Object.DontDestroyOnLoad(_gameplayCanvas); GameplayCanvas = _gameplayCanvas.AddComponent(); GameplayCanvas.renderMode = _canvasConfig.RenderMode; GameplayCanvas.sortingOrder = _canvasConfig.OrderInLayer; GameplayCanvas.planeDistance = _canvasConfig.PlaneDistance; var scaler = GameplayCanvas.AddComponent(); scaler.uiScaleMode = _canvasConfig.ScaleMode; scaler.referenceResolution = new Vector2(_canvasConfig.ReferenceResolutionX, _canvasConfig.ReferenceResolutionY); GameplayCanvas.AddComponent(); } private async UniTask LoadPanelConfigs() { _configsHandle = Addressables.LoadAssetsAsync(_configsLabel); await _configsHandle.ToUniTask(); _configs = _configsHandle.Result.ToDictionary(c => c.UIPanelType); } public void Dispose() { if (_configsHandle.IsValid()) Addressables.Release(_configsHandle); if (_canvasSettingsHandle.IsValid()) Addressables.Release(_canvasSettingsHandle); if (_gameplayCanvas) Addressables.ReleaseInstance(_gameplayCanvas); } } }