-
如图,通过OnPathDelegate回调获得Path,然后在 update 里面,通过调用 SeekFunc,角色行走在不可行走区域(绿色区域),直接穿过去了,没有沿可行走路径移动:
-
问题代码:
public void SeekFunc() { if (path==null) { stateMachine.SwitchState((int)PlayerStateEnum.Idle); Debug.Log($"path=========null, state={stateMachine.PlayerController.PlayerStateEnum}", stateMachine.PlayerController.gameObject); return; } try { ... Vector3 currentPos = stateMachine.PlayerController.transform.position; Vector3 targetWaypoint = path.vectorPath[currentPoint]; // 计算剩余路径距离 float remainingDistance = 0; for (int i = currentPoint; i < path.vectorPath.Count - 1; i++) { remainingDistance += Vector3.Distance(path.vectorPath[i], path.vectorPath[i + 1]); } remainingDistance += Vector3.Distance(currentPos, targetWaypoint); // 计算移动方向和距离 Vector3 moveDir = (targetWaypoint - currentPos).normalized; float playerSpeed = stateMachine.PlayerController.MoveSpeed; Vector3 rvoTarget = currentPos + moveDir * remainingDistance; // for (int i = currentPoint; i < path.vectorPath.Count - 2; i++) // { // Debug.DrawLine(path.vectorPath[i], path.vectorPath[i + 1],Color.red); // } // 设置RVO目标 rvoController.SetTarget(rvoTarget, playerSpeed, playerSpeed); // 应用RVO计算的移动 Vector3 movementDelta = rvoController.CalculateMovementDelta(Time.deltaTime); stateMachine.PlayerController.transform.position += movementDelta; // 更新朝向 if (movementDelta.magnitude > 0.01f) { var scale = stateMachine.PlayerController.Root.localScale; // 计算当前移动方向在等轴视角下的"水平"分量 float adjustedX = movementDelta.x - movementDelta.z; // 保存当前朝向状态(1为右,-1为左) int currentDirection = scale.x > 0 ? 1 : -1; // 只有当变化足够明显时才改变方向 float threshold = 0.03f; // 调整阈值大小控制朝向切换灵敏度 // 若当前方向与移动方向不一致,且差异显著,才切换方向 if ((currentDirection > 0 && adjustedX < -threshold) || (currentDirection < 0 && adjustedX > threshold)) { // 方向明显不同,切换朝向 scale.x = Mathf.Abs(scale.x) * (adjustedX > 0 ? 1 : -1); stateMachine.PlayerController.Root.localScale = scale; } } // 检查是否到达当前路径点 float moveNextDist = 1f; if (Vector3.Distance(currentPos, targetWaypoint) < moveNextDist) { currentPoint++; } } catch (Exception e) { // Debug.LogError(e); stateMachine.SwitchState((int)PlayerStateEnum.Idle); } }
-
解决,将 moveNextDist 改小为 0.1。
float moveNextDist = 0.1f;
if (Vector3.Distance(currentPos, targetWaypoint) < moveNextDist)
{
currentPoint++;
}