259 lines
8.0 KiB
C#
259 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)
|
|
{
|
|
// 同方格移动,不处理
|
|
_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.moveSpeed;
|
|
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<Vector3> CalcRoadLine()
|
|
{
|
|
return _roadPointList;
|
|
}
|
|
|
|
public int GetCurrentIndex()
|
|
{
|
|
return _currentPathIndex;
|
|
}
|
|
|
|
}
|
|
}
|