using System; using Code.Infrastructure.Configs; using Code.Infrastructure.EventBus; using Cysharp.Threading.Tasks; using Reflex.Core; using Reflex.Injectors; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Object = UnityEngine.Object; namespace Code.Example.Platformer.Entity { public interface IPlatformerPlayerFactory { UniTaskVoid WarmPlayer(); void ReleasePlayer(); void SpawnPlayer(Vector3 position); } public class PlatformerPlayerFactory : IPlatformerPlayerFactory, IDisposable { private EventBus _eventBus; private AssetReference _playerConfigReference; private AsyncOperationHandle _playerConfigHandle; private AsyncOperationHandle _playerPrefabHandle; private PlatformerEntitySettingsConfig _playerConfig; public PlatformerPlayerFactory(IConfigLocator configLocator, EventBus eventBus) { _eventBus = eventBus; _playerConfigReference = configLocator.TryGetConfigAssetReference(); LoadConfigs().Forget(); } private async UniTaskVoid LoadConfigs() { _playerConfigHandle = Addressables.LoadAssetAsync(_playerConfigReference); await _playerConfigHandle.ToUniTask(); _playerConfig = _playerConfigHandle.Result; _eventBus.RaiseEvent(x => x.PlatformerPlayerFactoryInitialized()); } public async UniTaskVoid WarmPlayer() { if (_playerPrefabHandle.IsValid()) { _eventBus.RaiseEvent(x => x.PlatformerPlayerLoaded()); return; } UnityEngine.Debug.LogWarning($"Player loaded"); _playerPrefabHandle = Addressables.LoadAssetAsync(_playerConfig.prefabReference); await _playerPrefabHandle.ToUniTask(); _eventBus.RaiseEvent(x => x.PlatformerPlayerLoaded()); } public void ReleasePlayer() { _playerPrefabHandle.Release(); } public void SpawnPlayer(Vector3 position) { var player = Object.Instantiate(_playerPrefabHandle.Result, position, Quaternion.identity); var racer = player.GetComponent(); racer.SetData(_playerConfig.EntityData); var health = player.GetComponent(); health.Setup(_playerConfig.EntityData.maxHealth, _playerConfig.EntityData.damageRecieveThreshold); GameObjectInjector.InjectObject(player, Container.RootContainer); // TODO САМОЕ НЕСТАБИЛЬНОЕ ДЕРЬМО ВО ВСЕЛЕННОЙ КОНТЕЙНЕР ДОЛЖЕН БЫТЬ КОНТЕКСТНЫМ _eventBus.RaiseEvent( x => x.PlatformerPlayerSpawned(player.GetComponent())); } public void Dispose() { UnityEngine.Debug.LogWarning($"Enemies released"); _playerPrefabHandle.Release(); _playerConfigHandle.Release(); } } public interface IPlatformerPlayerFactoryInitializedHandle : IGlobalSubscriber { public void PlatformerPlayerFactoryInitialized(); } public interface IPlatformerPlayerLoadedHandle : IGlobalSubscriber { public void PlatformerPlayerLoaded(); } public interface IPlatformerPlayerSpawnedHandle : IGlobalSubscriber { public void PlatformerPlayerSpawned(Entity entity); } }