using System; using Cysharp.Threading.Tasks; using Framework; using Gameplay.Character; using Gameplay.Character.Utils; using Gameplay.Level; using Gameplay.Summon; using Gameplay.Unit.Data; using Gameplay.Vehicle; using Gameplay.Vehicle.Impl; namespace Gameplay.Unit { public class GameUnitManager { /// /// 备战席的单位 /// public UnitContainer prepareUnits = new UnitContainer(); /// /// 战斗中的单位 /// public UnitContainer infightUnits = new UnitContainer(); /// /// 已死亡的单位 /// 注意这里不会有载具单位,载具单位死亡之后仍在存在于战斗中,只是处于损坏状态,可以被技能修复 /// public UnitContainer deadUnits = new UnitContainer(); /// /// 所有的单位,无论是否在备战席、战斗中、死亡,都能在这里找到 /// public UnitContainer totalUnits = new UnitContainer(); public CharacterManager characterManager; public VehicleManager vehicleManager; public SummonManager summonManager; private bool _needUpdateTargets; public static GameUnitManager instance { get; private set; } public static void CreateInstance() { instance = new GameUnitManager(); instance.Init(); } private GameUnitManager() { characterManager = new CharacterManager(); vehicleManager = new VehicleManager(); } public void Init() { _needUpdateTargets = true; _RegistEvents(); } private void _RegistEvents() { EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Register(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_DEAD, (Action)_OnCharacterDead); } private void _UnRegistEvents() { EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnAnyCharacterCellIndexChange); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_DEAD, (Action)_OnCharacterDead); } private void _OnCharacterDead(GameUnit deadCharacter) { _needUpdateTargets = true; } private void _OnAnyCharacterCellIndexChange(GameUnit noUse) { _needUpdateTargets = true; } public async UniTask PrepareUnits() { var selectTeam = TeamEditManager.Instance.GetSelectTeam(); var cIds = selectTeam.GetCharacterIDs(); for (int i = 0; i < cIds.Length; i++) { var cId = cIds[i]; var cInfo = CharacterDataInfoManager.Instance.GetCharacterInfo(cId); if (cInfo == null) { DebugUtil.LogError("不存在的角色id: {0}", cId); continue; } await PrepareCharacter(cInfo, ETroopsId.Self); } var vIds = selectTeam.GetVehicleIDs(); for (int i = 0; i < vIds.Length; i++) { var vId = vIds[i]; var vInfo = VehicleCultivateDataManager.Instance.GetVehicleCultivateData(vId); if (vInfo == null) { DebugUtil.LogError("不存在的载具id: {0}", vId); continue; } await PrepareVehicle(vInfo, ETroopsId.Self); } } private void _PrepareUnit(GameUnit unit) { prepareUnits.Add(unit); totalUnits.Add(unit); DebugUtil.LogG($"单位:{unit.GetID()} 已进入备战席"); } public async UniTask PrepareNpc(LevelData.NPCInfo npcInfo, int troopId) { var nGuid = GUIDManager.GenGuid(); var dataConfig = CharacterDataHelper.CombineConfigData(npcInfo.id, npcInfo.level); var createUnit = new Character.Character(nGuid, dataConfig, troopId); await createUnit.LoadAsync(); await createUnit.Prepare(); _PrepareUnit(createUnit); return createUnit; } public async UniTask PrepareCharacter(CharacterDataInfo cInfo, int troopId) { var nGuid = GUIDManager.GenGuid(); var dataConfig = CharacterDataHelper.CombineConfigData(cInfo); var createUnit = new Character.Character(nGuid, dataConfig, troopId); await createUnit.LoadAsync(); await createUnit.Prepare(); _PrepareUnit(createUnit); return createUnit; } public async UniTask PrepareVehicle(VehicleCultivateData vInfo, int troopId) { var nGuid = GUIDManager.GenGuid(); var dataConfig = VehicleDataHelper.CombineConfigData(vInfo); var createUnit = new NormalVehicle(nGuid, dataConfig, troopId); await createUnit.Create(); await createUnit.Prepare(); _PrepareUnit(createUnit); return createUnit; } public BaseSummon PrepareSummon(int summondId, GameUnit creator) { var createSummon = SummonFactory.CreateSummon(summondId, creator); _PrepareUnit(createSummon); return createSummon; } // 将单位移动到备战席 public void MoveUnitToPrepare(uint unitGuid) { var unit = infightUnits.Search(unitGuid); if (unit == null) { DebugUtil.LogError("不存在的单位:{0}", unitGuid); return; } // 判断是否已经开展 if (LevelManager.Instance.CurrentLevel.isInBattle) { unit.ExitBattle(); } unit.BackPrepare(); // 转移 infightUnits.Remove(unit); prepareUnits.Add(unit); DebugUtil.LogG($"单位:{unit.GetID()} 从战斗列表回到备战席"); } // 将到位移动到战斗中,并指定位置 public void MoveUnitToFight(uint unitGuid, int cellIndex, float yaw) { var unit = prepareUnits.Search(unitGuid); if (unit == null) { DebugUtil.LogError("不存在的单位:{0}", unitGuid); return; } // 设置位置 unit.SetPosAndYaw(cellIndex, yaw); unit.Ready(); // 判断是否已经开战 if (LevelManager.Instance.CurrentLevel.isInBattle) { unit.EnterBattle(); } // 转移 prepareUnits.Remove(unit); infightUnits.Add(unit); DebugUtil.LogG($"单位:{unit.GetID()} 已进入战斗序列"); } public void EnterBattle() { _needUpdateTargets = true; for (int i = 0; i < infightUnits.count; i++) { var unit = infightUnits.GetByIndex(i); unit.EnterBattle(); } } public void LogicUpdate(float dt) { if (_needUpdateTargets) { _needUpdateTargets = false; _UpdateTargets(); } for (int i = 0; i < infightUnits.count; i++) { var unit = infightUnits.GetByIndex(i); unit.LogicUpdate(dt); if (unit.needRemove) { DebugUtil.LogG($"单位:{unit.GetID()} 已移除"); unit.ExitBattle(); infightUnits.RemoveAt(i); deadUnits.Add(unit); i--; } } } private void _UpdateTargets() { for (int i = 0; i < infightUnits.count; i++) { var unit = infightUnits.GetByIndex(i); switch (unit.gameunitType) { case EGameUnitType.Character: if (unit is Character.Character character) character.UpdateTargets(); break; case EGameUnitType.Vehicle: if (unit is NormalVehicle vehicle) vehicle.UpdateTargets(); break; } } } public void Dispose() { _UnRegistEvents(); for (int i = 0; i < infightUnits.count; i++) { var unit = infightUnits.GetByIndex(i); unit.ExitBattle(); } characterManager.Dispose(); instance = null; } } }