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

262 lines
8.0 KiB
C#

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<int> _tgsPath;
private int _currentPathIndex;
private Map _map;
private Vector3 _targetPosition;
private int _lastTargetCellIndex;
private readonly List<Vector3> _roadPointList;
private float _lastMoveSpeed;
public VehicleStateMove(NormalVehicle owner) : base(owner, EVehicleState.Move)
{
_tgsPath = new List<int>();
_roadPointList = new List<Vector3>();
}
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)
{
// 同方格移动,不处理
var canMove = PathFinder.CanPass(currentMoveCellIndex, owner);
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)
{
if (owner.controlData.targetCellIndex != owner.transData.cellIndex)
{
// 重新寻路
isFinished = true;
nextState = EDownState.Move;
return;
}
// 到达终点
isFinished = true;
nextState = EVehicleState.Stop;
owner.controlData.targetCellIndex = -1;
Framework.EventManager.Instance.Send(Framework.EventManager.EventName.LevelCharacterArriveBlock, owner);
}
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, to, owner);
// 再次判定是否可以直接走通
if (_IsFathExist())
{
_targetPosition = _map.TGSCellIndex2WorldPosition(_tgsPath[_currentPathIndex]);
}
else
{
owner.Log($"无有效路径: from:{from} to:{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);
}
if (!_tgsPath.Contains(owner.controlData.targetCellIndex))
{
var targetPos = _map.TGSCellIndex2WorldPosition(owner.controlData.targetCellIndex);
_roadPointList.Insert(0, targetPos);
}
}
public List<Vector3> CalcRoadLine()
{
return _roadPointList;
}
public int GetCurrentIndex()
{
return _currentPathIndex;
}
}
}