using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.Configs; using Code.Infrastructure.EventBus; using Code.Infrastructure.Generators; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; namespace Code.Example.Platformer.Entity { [Config("Configs/Gameplay/Platformer/EntitySettings", true)] public class PlatformerEntitySettings { [ToConfig] public PlatformerEntityData EntityData; [ToConfig] public AssetReference prefabReference; } [Serializable] public struct PlatformerEntityData { public string name; public float speed; public float acceleration; public int damage; public PlatformerEntityType type; public int maxHealth; } public enum PlatformerEntityType { Player, Boar, Bee, Snail } public class PlatformerEnemyFactory { private EventBus _eventBus; private string _enemyConfigsLabel; private AsyncOperationHandle> _enemyConfigsHandle; private Dictionary> _enemyPrefabsHandle = new(); private Dictionary _enemyConfigs; public PlatformerEnemyFactory(IConfigLocator configLocator, EventBus eventBus) { _eventBus = eventBus; _enemyConfigsLabel = configLocator.TryGetManyConfigAssetReferences(); LoadConfigs().Forget(); } private async UniTaskVoid LoadConfigs() { _enemyConfigsHandle = Addressables.LoadAssetsAsync(_enemyConfigsLabel); await _enemyConfigsHandle.ToUniTask(); _enemyConfigs = _enemyConfigsHandle.Result.ToDictionary(x => x.racerData.type); _enemyConfigs.Remove(PlatformerEntityType.Player); _eventBus.RaiseEvent(x => x.PlatformerFactoryInitialized()); } public async UniTaskVoid LoadRacer(PlatformerEntityType racerType) { if (racerType == PlatformerEntityType.Player) return; if (_enemyPrefabsHandle.ContainsKey(racerType)) { _eventBus.RaiseEvent(x => x.PlatformerEnemyLoaded(racerType, null)); return; } UnityEngine.Debug.LogWarning($"Racer loaded {racerType}"); _enemyPrefabsHandle.Add(racerType, Addressables.LoadAssetAsync(_enemyConfigs[racerType].prefabReference)); await _enemyPrefabsHandle[racerType].ToUniTask(); var racer = _enemyPrefabsHandle[racerType].Result.GetComponent(); racer.SetData(_enemyConfigs[racerType].racerData); _eventBus.RaiseEvent(x => x.PlatformerEnemyLoaded(racerType, racer)); } public void ReleaseRacer(PlatformerEntityType racerType) { _enemyPrefabsHandle[racerType].Release(); _enemyPrefabsHandle.Remove(racerType); } public void Dispose() { UnityEngine.Debug.LogWarning($"Racers released"); foreach (var prefab in _enemyPrefabsHandle) prefab.Value.Release(); _enemyPrefabsHandle.Clear(); _enemyConfigsHandle.Release(); } } public interface IPlatformerFactoryInitializedHandle : IGlobalSubscriber { public void PlatformerFactoryInitialized(); } public interface IPlatformerEnemyLoadedHandle : IGlobalSubscriber { public void PlatformerEnemyLoaded(PlatformerEntityType type, Entity entity); } }