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()
{
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();
characterManager.Dispose();
instance = null;
}
}
}