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

Unity 2D敌人巡逻问题:敌人瞬移而非平滑移动求助

敌人巡逻瞬移问题的修复方案

问题根源

  • 缺少帧延迟导致瞬间完成插值:Patrol协程的死循环中没有yield return null,所有移动逻辑会在一帧内执行完毕,直接跳到目标点
  • Lerp未结合Time.deltaTime:Vector2.Lerp的第三个参数直接使用Speed,未乘以Time.deltaTime,导致移动速度完全不受帧率控制,甚至一帧内完成插值

修复后的代码

首先补充Awake初始化逻辑避免空引用,再修改Patrol协程:

protected virtual void Awake()
{
    // 初始化当前敌人对象,避免空引用错误
    CurrentEnemy = gameObject;
}

protected virtual IEnumerator Patrol()
{
    Transform nextTargetPoint = EnemyFirstPosition;

    while (true)
    {
        // 处理目标点为空的情况
        if (nextTargetPoint == null)
        {
            nextTargetPoint = EnemyFirstPosition;
            yield return null;
            continue;
        }

        // 结合Time.deltaTime实现帧率无关的平滑移动
        // Speed值建议设置为2-5之间的合理数值
        CurrentEnemy.transform.position = Vector2.Lerp(
            CurrentEnemy.transform.position,
            nextTargetPoint.position,
            Speed * Time.deltaTime
        );

        // 使用sqrMagnitude替代magnitude,减少开平方运算的性能开销
        float distanceSquared = (CurrentEnemy.transform.position - nextTargetPoint.position).sqrMagnitude;
        // 0.01是0.1的平方,对应原判断的距离阈值
        if (distanceSquared < 0.01f)
        {
            // 在目标点停留1秒
            yield return new WaitForSeconds(1);
            // 切换到下一个巡逻点
            nextTargetPoint = nextTargetPoint == EnemyFirstPosition ? EnemySecondPosition : EnemyFirstPosition;
        }

        // 每帧等待一次,让移动逻辑逐帧执行
        yield return null;
    }
}

额外注意事项

  • 确保在Inspector面板中给EnemyFirstPosition和EnemySecondPosition正确赋值
  • 检查Speed变量是否设置了非零的合理值(比如2f,数值过大仍可能导致快速移动看起来像瞬移)
  • 状态切换时建议添加协程停止逻辑,比如切换到Chase/Attack状态时调用StopCoroutine(Patrol()),避免协程后台继续执行

内容的提问来源于stack exchange,提问作者JULUXX JULUX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:33:18