using System; using System.Collections.Generic; using System.Linq; 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 UnityEngine.SceneManagement; namespace Code.Example.Platformer.Entity { public interface IPlatformerPlayerFactory { UniTaskVoid LoadPlayer(); void ReleasePlayer(); UniTaskVoid 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 LoadPlayer() { if (_playerPrefabHandle.IsValid()) { _eventBus.RaiseEvent(x => x.PlatformerPlayerLoaded()); return; } UnityEngine.Debug.LogWarning($"Player loaded"); _playerPrefabHandle = Addressables.LoadAssetAsync(_playerConfig.prefabReference); await _playerPrefabHandle.ToUniTask(); var racer = _playerPrefabHandle.Result.GetComponent(); racer.SetData(_playerConfig.EntityData); _eventBus.RaiseEvent(x => x.PlatformerPlayerLoaded()); } public void ReleasePlayer() { _playerPrefabHandle.Release(); } public async UniTaskVoid SpawnPlayer(Vector3 position) { var player = await Addressables.InstantiateAsync(_playerConfig.prefabReference, position, Quaternion.identity).ToUniTask(); 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); } }