Unity中Rigidbody2D.MovePosition靠近目标减速:如何让敌人匀速追击?
解决敌人恒定速度追击玩家的问题
我完全懂你现在的烦恼——本来想让敌人以全速猛冲过来撞玩家,结果它远的时候跑得快,靠近就减速,追击的压迫感直接没了。咱们来拆解代码里的问题,然后快速修复它。
问题根源分析
你的代码里有两个关键问题导致了速度不稳定:
- 没有适配物理更新的时间步长:
FixedUpdate的执行间隔是固定的,但你直接用speed乘以方向向量,没有乘以Time.fixedDeltaTime。这会导致不同设备或帧率下,敌人的实际移动速度不一致,甚至出现忽快忽慢的情况。 - 错误的位置基准:你用
transform.position来计算新位置,但Transform的位置可能会被物理引擎的其他操作(比如碰撞修正)干扰,导致移动计算出现偏差,间接让速度看起来“变慢”了。
修正后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Dotty : MonoBehaviour { [SerializeField] Transform playerTarget; Vector3 direction; Rigidbody2D rb; [SerializeField] float speed = 2.2f; // 改为可序列化,方便在编辑器里实时调参 void Start() { rb = GetComponent<Rigidbody2D>(); // 建议:如果不需要重力,把Rigidbody2D的Gravity Scale设为0 rb.gravityScale = 0; } void Update() { // 提前归一化方向向量,避免FixedUpdate里重复计算 direction = (playerTarget.position - transform.position).normalized; // 保持敌人朝向玩家 float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; rb.rotation = angle; } private void FixedUpdate() { // 基于Rigidbody的当前位置计算新位置,乘以Time.fixedDeltaTime保证速度恒定 Vector2 newPosition = rb.position + (Vector2)direction * speed * Time.fixedDeltaTime; rb.MovePosition(newPosition); } }
关键修改说明
- 提前归一化方向:在
Update里就把方向向量归一化,避免FixedUpdate里重复做相同计算,小幅度提升性能。 - 使用Rigidbody位置作为基准:用
rb.position替代transform.position,确保物理计算的准确性,避免碰撞等操作干扰移动逻辑。 - 加入Time.fixedDeltaTime:这是保证恒定速度的核心——不管
FixedUpdate每秒执行多少次,敌人的移动速度都会稳定在speed(单位:世界单位/秒)。 - 优化调试体验:把
speed设为[SerializeField],不用改代码就能在Unity编辑器里调整速度,快速测试效果。 - 关闭重力干扰:如果敌人不需要受重力影响,直接在Start里把
gravityScale设为0,防止重力拖慢移动速度。
额外小贴士
如果想要敌人转向更平滑(比如不会瞬间扭头),可以用Mathf.Lerp来过渡角度,但这会让追击的“凶猛感”下降,适合更笨拙的敌人。如果要保持全速猛冲的效果,当前的直接朝向逻辑就足够了。
内容的提问来源于stack exchange,提问作者PhiCato
相关产品推荐
相关产品推荐

