using System; using System.Collections.Generic; using Gameplay.Character; using Gameplay.Level; using Gameplay.Vehicle.Impl; using LTGame; using UnityEngine; namespace Gameplay.Vehicle.State { public class VehicleStateMove : BaseVehicleState { private List _tgsPath; private int _currentPathIndex; private Map _map; private Vector3 _targetPosition; private int _lastTargetCellIndex; private readonly List _roadPointList; private float _lastMoveSpeed; public VehicleStateMove(NormalVehicle owner) : base(owner, EVehicleState.Move) { _tgsPath = new List(); _roadPointList = new List(); } protected override void _OnEnter(NBaseState exitState, object param) { base._OnEnter(exitState, param); if (owner.controlData.followUnit != null && owner.controlData.targetEnemy != owner.controlData.followUnit) { owner.controlData.targetCellIndex = owner.controlData.followUnit.transData.cellIndex; } _lastTargetCellIndex = owner.controlData.targetCellIndex; _map = LevelManager.Instance.CurrentLevel.Map; // 初始化路径 _FindPath(); if (isFinished) return; owner.statusData.isMoveing = true; owner.vAnim.targetAnim = "move"; } protected override void _OnRunning() { base._OnRunning(); owner.fightData.lastMoveTime = LevelManager.Instance.CurrentLevel.LevelTime; if (owner.aliveData.currentHp <= 0) { isFinished = true; nextState = EVehicleState.Destroy; return; } // 如果目标改变,则重新寻路 if (_lastTargetCellIndex != owner.controlData.targetCellIndex) { isFinished = true; nextState = EVehicleState.Move; return; } // 持续判断当前索引格子是否可移动 var currentMoveCellIndex = _tgsPath[_currentPathIndex]; var islocalMove = currentMoveCellIndex == owner.transData.cellIndex; if (!islocalMove) { // 同方格移动,不处理 _map.GetRuntimeBlockProperty(currentMoveCellIndex, out var blockData); var canMove = MapUtils.CanPass(owner.commonData.crossLevel, blockData); if (!canMove) { isFinished = true; nextState = EVehicleState.Move; return; } } _DoMove(); } protected override void _OnExit(NBaseState exitState, object param) { base._OnExit(exitState, param); owner.statusData.isMoveing = false; } private void _DoMove() { if (!_DirectMoveTo(_targetPosition, deltaTime)) { var followUnit = owner.controlData.followUnit; if (followUnit != null) // 有追踪对象 { if (followUnit == owner.controlData.targetEnemy) { // 目标一致,则停下 owner.controlData.targetCellIndex = owner.transData.cellIndex; // 重算路径 _FindPath(); return; } else { // 目标不一致,继续向目标移动 var followCellIndex = followUnit.transData.cellIndex; if (followCellIndex != owner.controlData.targetCellIndex) { // 重算路径 isFinished = true; nextState = EVehicleState.Move; return; } } } // 还在走,就继续走 return; } // 到达转折点 _currentPathIndex++; if (_currentPathIndex >= _tgsPath.Count) { // 到达终点 isFinished = true; nextState = EVehicleState.Stop; owner.controlData.targetCellIndex = -1; if (LevelManager.Instance.CurrentLevel.selectUnit == owner) { SelecterView.Instance.SetSelectAndTarget(owner.Node, null); } Framework.EventManager.Instance.Send(Framework.EventManager.EventName.LevelCharacterArriveBlock, new EDArriveBlock() { characterId = owner.GetID(), cellIndex = owner.transData.cellIndex }); } else { var newCellIndex = _tgsPath[_currentPathIndex]; // 更新目标点 _targetPosition = _map.TGSCellIndex2WorldPosition(newCellIndex); } } private bool _DirectMoveTo(Vector3 pos, float dt) { var currentPos = owner.transData.pos; var toTarget = pos - currentPos; toTarget.y = 0; _RotateToBlock(toTarget, dt); var requireDistance = toTarget.magnitude; var moveSpeed = owner.fightData.GetMoveSpeed(); var moveDt = dt * moveSpeed; if (moveDt < requireDistance) { var moveDir = toTarget.normalized; var moveDistance = moveDt * moveDir; var newPos = currentPos + moveDistance; owner.transData.pos = newPos; return false; } else { // 直接到达目标点 owner.transData.pos = pos; return true; } } private void _RotateToBlock(Vector3 toTarget, float dt) { var toAngle = Vector3.SignedAngle(Vector3.forward, toTarget, Vector3.up); var currentAngle = owner.transData.yaw; if (Math.Abs(toAngle - currentAngle) > 0.1f) { var turnSpeed = owner.fightData.turnSpeed; var turnDt = dt * turnSpeed; var newAngle = Mathf.MoveTowardsAngle(currentAngle, toAngle, turnDt); owner.transData.yaw = newAngle; } } private bool _IsFathExist() { return !(_tgsPath == null || _tgsPath.Count <= 0); } private void _FindPath() { if (_map == null) return; _roadPointList.Clear(); _currentPathIndex = 0; var to = owner.controlData.targetCellIndex; var from = owner.transData.cellIndex; _tgsPath = PathFinder.FindPath(_map, from, to, owner.commonData.crossLevel); // 再次判定是否可以直接走通 if (_IsFathExist()) { _targetPosition = _map.TGSCellIndex2WorldPosition(_tgsPath[_currentPathIndex]); } else { owner.Log(string.Format("无有效路径: from:{0} to:{1}", from, to)); isFinished = true; nextState = EDownState.Idle; // 停止到当前节点 owner.StopToCurrentCell(); } for (var i = _tgsPath.Count - 1; i >= 0; --i) { var tgsIndex = _tgsPath[i]; var worldPos = _map.TGSCellIndex2WorldPosition(tgsIndex); _roadPointList.Add(worldPos); } } public List CalcRoadLine() { return _roadPointList; } public int GetCurrentIndex() { return _currentPathIndex; } } }