You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:39:09