using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using BITKit; using BITKit.Entities; using BITKit.WorldNode; using Cysharp.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Project.B.CharacterController; using Project.B.Entities; using Project.B.Map; using UnityEngine; using UnityEngine.AI; namespace Project.B.Player { public class GameMapPlayerService:IDisposable { private readonly IEntitiesService _entitiesService; private readonly IGameMapService _gameMapService; private readonly IPlayerFactory _playerFactory; private readonly INpcFactory _npcFactory; private UniTaskCompletionSource _player=new(); private readonly ILogger _logger; private bool _isDisposed; public GameMapPlayerService(IPlayerFactory playerFactory, IGameMapService gameMapService, INpcFactory npcFactory, IEntitiesService entitiesService, ILogger logger) { _playerFactory = playerFactory; _gameMapService = gameMapService; _npcFactory = npcFactory; _entitiesService = entitiesService; _logger = logger; _entitiesService.OnAdd += OnAdd; _gameMapService.OnTaskStatusChanged += OnTaskStatusChanged; _gameMapService.OnMapChanging += OnMapChanging; } private async UniTask OnMapChanging(string arg) { await _player.Task; } private async void OnAdd(IEntity entity) { if (entity.ServiceProvider.QueryComponents(out WorldInfoNpcStartNode _) is false) return; entity.ServiceProvider.QueryComponents(out GameObject gameObject); if(!gameObject)return; var gameObjectName = gameObject.name; await UniTask.NextFrame(); if(_isDisposed)return; try { var npc = await _npcFactory.CreateAsync(null, entity.ServiceProvider.QueryComponents(out Animator _) ? gameObject : null); if (npc.ServiceProvider.QueryComponents(out ICharacterController characterController)) { characterController.Position = gameObject.transform.position; characterController.Rotation = gameObject.transform.rotation; } else if (npc.ServiceProvider.QueryComponents(out NavMeshAgent agent)) { agent.transform.rotation = gameObject.transform.rotation; } else if (npc.ServiceProvider.QueryComponents(out Transform transform)) { transform.SetPositionAndRotation(gameObject.transform.position, gameObject.transform.rotation); } } catch (Exception) { _logger.LogError($"{gameObjectName}创建失败",gameObject); throw; } } private async void OnTaskStatusChanged(TaskStatus arg1, TaskStatus arg2) { switch (arg2) { case TaskStatus.Created: _playerFactory.Dispose(); break; case TaskStatus.RanToCompletion: _player.TrySetResult(await _playerFactory.CreateAsync(null,null)); _player = new(); break; } } public void Dispose() { _gameMapService.OnTaskStatusChanged -= OnTaskStatusChanged; _entitiesService.OnAdd -= OnAdd; _isDisposed = true; } } }