Unity敌人脚本异常:敌人无视重力悬空,求排查移动方法问题
敌人悬空无视重力问题排查与修复
核心问题原因
Rb.MovePosition的错误用法:你在Update中直接用transform.position + dir * Speed计算目标位置,完全覆盖了Rigidbody2D受重力影响的Y轴位移,相当于强制将敌人固定在你计算的位置上,直接导致重力失效。- 未做时间增量处理:移动速度未乘以
Time.deltaTime,移动速率会和帧率绑定,同时未归一化的方向向量会让敌人离玩家越远移动越快,完全不符合匀速追踪逻辑。 - 方向向量未归一化:
dir = Player.transform.position - transform.position是带长度的向量,直接乘以Speed会导致移动速度随距离变化,逻辑混乱。
修复方案
推荐两种符合Unity 2D物理逻辑的写法,二选一即可:
方式一:修改Velocity(保留重力影响)
替换原Rb.MovePosition代码,改为仅控制水平方向速度,保留重力对Y轴的作用,同时将物理操作移到FixedUpdate(物理相关代码必须在固定帧率周期执行):
// 把这段代码从Update移到FixedUpdate中 if (Aggro && ShouldWalking) { Vector3 dir = Player.transform.position - transform.position; dir.y = 0; // 只处理水平移动,保留Y轴的重力效果 dir.Normalize(); // 仅设置X轴速度,Y轴保持刚体自身的重力速度 Rb.velocity = new Vector2(dir.x * Speed, Rb.velocity.y); }
方式二:正确使用MovePosition(兼容物理交互)
如果坚持使用MovePosition,需要基于刚体当前位置(已包含重力影响)计算目标点,并加入时间增量:
// 把这段代码从Update移到FixedUpdate中 if (Aggro && ShouldWalking) { Vector3 dir = Player.transform.position - Rb.position; dir.y = 0; // 保留Y轴重力作用 dir.Normalize(); Vector3 targetPos = Rb.position + dir * Speed * Time.fixedDeltaTime; Rb.MovePosition(targetPos); }
额外优化建议
- 仇恨状态重置:当前代码只有
Aggro = true的触发逻辑,没有离开仇恨范围后的重置逻辑,建议在PlayerFind.Length == 0时添加Aggro = false的判断(可根据需求调整离开范围的判定条件)。 - 组件缓存:不要在
Update中反复调用GetComponent<Animator>(),在Start中缓存为成员变量,提升性能。 - 避免硬编码数值:Attack协程中硬编码
Speed = 0.059f,建议改为使用公开的初始速度变量(如public float DefaultSpeed = 0.059f),后续重置时直接赋值该变量,便于维护。
内容的提问来源于stack exchange,提问作者Aseed Kid
相关产品推荐
相关产品推荐

