NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Character/Character.State.cs

188 lines
6.1 KiB
C#

using Gameplay.Unit;
namespace Gameplay.Character
{
using Level;
using Skill;
using LTGame;
public partial class Character
{
private NStateMachine<BaseCharacterState> _downFSM;
private NStateMachine<BaseCharacterState> _upFSM;
private NStateMachine<BaseCharacterState> _fullFSM;
// private List<GameUnit> _cacheEnemyList = new List<GameUnit>();
public NStateMachine<BaseCharacterState> downFSM
{
get => _downFSM;
}
public NStateMachine<BaseCharacterState> upFSM
{
get => _upFSM;
}
public NStateMachine<BaseCharacterState> fullFSM
{
get => _fullFSM;
}
private void _InitFsm()
{
_downFSM = new NStateMachine<BaseCharacterState>();
_downFSM.Add(new DownStateIdle(this));
_downFSM.Add(new DownStateMove(this));
_downFSM.Add(new DownStateEmpty(this));
_upFSM = new NStateMachine<BaseCharacterState>();
_upFSM.Add(new UpStateIdle(this));
_upFSM.Add(new UpStateNormalShoot(this));
_upFSM.Add(new UpStateReload(this));
_upFSM.Add(new UpStateEmpty(this));
_upFSM.Add(new UpStateLowShoot(this));
_fullFSM = new NStateMachine<BaseCharacterState>();
_fullFSM.Add(new FullStateEmpty(this));
_fullFSM.Add(new FullStateDead(this));
_fullFSM.Add(new FullStateReady(this));
_fullFSM.Add(new FullStateSkill(this));
_fullFSM.Add(new FullStateWaitRemove(this));
_fullFSM.Add(new FullStateRetreat(this));
_fullFSM.Add(new FullStateFadeOut(this));
_fullFSM.Add(new FullStateOnVehicle(this));
_fullFSM.Add(new FullStateUpVehicle(this));
_fullFSM.Add(new FullStateDeadOnVehicle(this));
_fullFSM.Add(new FullStateStun(this));
_fullFSM.ChangeState(EFullState.Ready);
}
public void Start()
{
_downFSM.ChangeState(EDownState.Idle);
_upFSM.ChangeState(EUpState.Idle);
}
public void ResetToPrepare()
{
_fullFSM.ChangeState(EFullState.Ready);
statusData.Reset();
controlData.Reset();
runtimeData.ResetToPrepare();
}
protected override void _OnLogicUpdate(float dt)
{
if (_fullFSM == null) return;
if (SkillManager.instance.needSkillPaused && SkillManager.instance.inSkillingUnit != this)
{
return;
}
// 角色才更新这个
delayMoraleDamage.LogicUpdate(dt);
runtimeData.LogicUpdate(dt);
_fullFSM.LogicUpdate(dt);
_downFSM.LogicUpdate(dt);
_upFSM.LogicUpdate(dt);
_ViewUpdate(dt);
}
public void UpdateTargets()
{
// 已经死亡则不再索敌
if (statusData.isDead) return;
// 放技能时不索敌
if (statusData.isInSkilling) return;
var selfCellIndex = transData.cellIndex;
var map = LevelManager.Instance.CurrentLevel.Map;
var minDistance = fightData.attackDistance + 1;
// 强制索敌逻辑
var followUnit = controlData.followUnit;
if (followUnit != null && Level.IsEnemy(this, followUnit))
{
if (!followUnit.statusData.CheckCanBeTarget())
{
controlData.followUnit = null;
}
else
{
// 判定范围
var followCellIndex = followUnit.transData.cellIndex;
var cellDistance = map.TerrainGridSystem.CellGetHexagonDistance(selfCellIndex, followCellIndex);
if (cellDistance < minDistance)
{
controlData.targetEnemy = followUnit;
return;
}
// 不在攻击范围内,向目标移动
}
}
// _cacheEnemyList.Clear();
// LevelManager.Instance.CurrentLevel.CharacterManager.SearchEnemies(this, _cacheEnemyList);
// controlData.targetEnemy = null;
GameUnit target = null;
var allUnits = GameUnitManager.instance.infightUnits;
for (var i = 0; i < allUnits.count; ++i)
{
var enemy = allUnits.GetByIndex(i);
if (enemy == null) continue;
if (!enemy.statusData.CheckCanBeTarget()) continue;
if (enemy == this) continue;
if (!statusData.isChaos && !Level.IsEnemy(this, enemy)) continue;
var enemyCellIndex = enemy.transData.cellIndex;
var cellDistance = map.TerrainGridSystem.CellGetHexagonDistance(selfCellIndex, enemyCellIndex);
if (cellDistance < minDistance)
{
minDistance = cellDistance;
target = enemy;
}
}
if (target != controlData.targetEnemy)
{
if (target != null)
{
Log("目标切换:" + target.Node.Name);
}
else
{
Log("丢失目标");
}
}
controlData.targetEnemy = target;
}
private void _ViewUpdate(float dt)
{
if (Node?.GameObject == null) return;
// 更新trans
if (transData.isTransChanged)
{
Node.GameObject.transform.SetPositionAndRotation(transData.pos, transData.rot);
}
transData.Reset();
// 更新动画
if (cAnim != null)
{
cAnim.isFullControl = runtimeData.isFullControl;
cAnim.ViewUpdate(dt);
}
// 更新武器
if (weapon != null)
{
weapon.ViewUpdate(dt);
}
}
}
}