Unity 2D物体向随机路径点移动功能异常求解
问题原因
- 核心逻辑错误:
MoveToNextWayPoint()方法没有做到达判定,每帧都会无条件调用GetNextWayPoint()刷新随机目标点,目标位置每帧都在变化,物体自然会出现乱跳、看似同时向多个位置移动的表现。 - 浮点数精度bug:直接用
transform.position != currentTargetPoint.position做位置相等判断,Vector3坐标为浮点数类型,移动过程中几乎不可能和目标点坐标值完全相等,会导致判定逻辑持续异常。 - 状态逻辑缺失:到达目标点后没有重置
isMoving标记和移动动画参数,状态不闭环。
修改方案
调整核心移动逻辑,遵循「到达当前点才切换新目标,未到达时持续朝固定当前目标移动」的规则:
- 新增极小的到达判定阈值(2D项目可设为0.05f~0.1f),用距离判断替代坐标值直接判等,规避浮点数精度问题
- 仅当物体抵达当前目标点时,才调用随机方法获取下一个目标点
- 未到达目标时不刷新目标,持续执行移动逻辑
- 到达点位时同步复位移动状态
修改后的完整代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PathFinder : MonoBehaviour { [SerializeField] List<Transform> pathPoints; [SerializeField] Transform pathPrefab; [SerializeField] float moveSpeed = 10f; [SerializeField] bool isMoving = false; [SerializeField] bool isH_Attacking = false; Animator anim; Transform defaultWayPoint; Transform currentTargetPoint; // 到达判定阈值,可根据2D单位大小调整 const float reachThreshold = 0.08f; void Awake() { anim = GetComponent<Animator>(); defaultWayPoint = pathPrefab.GetChild(0); } void Start() { transform.position = defaultWayPoint.position; // 初始化第一个随机目标点 currentTargetPoint = pathPoints[Random.Range(0, pathPoints.Count)]; } void MoveToNextWayPoint() { // 判定是否到达当前目标点 if (Vector3.Distance(transform.position, currentTargetPoint.position) <= reachThreshold) { // 到达后才获取下一个新目标 GetNextWayPoint(); // 复位移动状态 isMoving = false; anim.SetBool("isMoving", false); return; } // 未到达目标时,固定朝当前目标移动,不刷新目标 float delta = moveSpeed * Time.deltaTime; transform.position = Vector3.MoveTowards(transform.position, currentTargetPoint.position, delta); anim.SetBool("isMoving", true); isMoving = true; } Transform GetNextWayPoint() { // 可选优化:避免随机到和当前完全相同的点位 Transform newTarget; do { newTarget = pathPoints[Random.Range(0, pathPoints.Count)]; } while (newTarget == currentTargetPoint && pathPoints.Count > 1); currentTargetPoint = newTarget; Debug.Log(currentTargetPoint.position); return currentTargetPoint; } void Update() { MoveToNextWayPoint(); } }
可选优化说明:如果路径点列表长度大于1,do-while循环可以避免物体抽到和当前相同的点位导致原地不动;如果列表长度为1,删掉这段判断直接随机即可。
内容的提问来源于stack exchange,提问作者NiftyRunner
相关产品推荐
相关产品推荐

