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

使用Rigidbody.MovePosition/MoveRotation时角色停止后小幅旋转问题排查

问题

使用Rigidbody的MovePosition和MoveRotation实现角色平滑移动与旋转,需求为通过WSAD键控制角色旋转并沿当前方向前进。移动过程正常,但停止输入后角色有时会出现10-20度的小幅旋转,请问是代码问题还是其他原因?该如何修复?

原代码

Rigidbody rb;
private float h_Input;
private float v_Input;

private Vector3 direction;
public float moveSpeed = 8;
public float rotateSpeed = 20;

void Start()
{
    rb = GetComponent<Rigidbody>();
}

void Update()
{
    
}

private void FixedUpdate()
{
    Move();     
}

private void Move()
{
    h_Input = Input.GetAxisRaw("Horizontal");
    v_Input = Input.GetAxisRaw("Vertical");

    if (h_Input!=0|| v_Input !=0)
    {
        direction = new Vector3(h_Input, 0, v_Input);
        
        Quaternion rotationTarget = Quaternion.LookRotation(direction, Vector3.up );
        rb.MoveRotation(Quaternion.Lerp(rb.rotation,rotationTarget, rotateSpeed * Time.fixedDeltaTime));
       
        rb.MovePosition(rb.position + transform.TransformDirection(Vector3.forward) * moveSpeed * Time.fixedDeltaTime);
    }
}

原因分析

这是代码逻辑+物理引擎微小干扰共同导致的问题:

  1. 输入停止时,代码终止了旋转更新,但此时角色旋转可能还没完全插值到目标角度,后续没有逻辑维持旋转状态;
  2. Quaternion.Lerp的特性是越接近目标插值速度越慢,可能导致最后几次输入中断时,目标旋转未完成;
  3. 刚体默认的角阻力可能不足,停止输入后残留的微小角速度会引发旋转偏移。

修复方案

修改点说明

  • 输入中断时主动锁定旋转、清除角速度,避免物理层面的偏移;
  • 用Quaternion.RotateTowards替代Lerp,以固定步长旋转,确保能精准到达目标角度;
  • 归一化输入方向,避免斜向输入时方向向量长度异常;
  • 增大刚体角阻力,减少物理干扰。

修改后的代码

Rigidbody rb;
private float h_Input;
private float v_Input;

private Vector3 direction;
public float moveSpeed = 8;
public float rotateSpeed = 20;

void Start()
{
    rb = GetComponent<Rigidbody>();
    // 增大角阻力,防止残留角速度引发旋转
    rb.angularDrag = 10f;
}

void Update()
{
    
}

private void FixedUpdate()
{
    Move();     
}

private void Move()
{
    h_Input = Input.GetAxisRaw("Horizontal");
    v_Input = Input.GetAxisRaw("Vertical");

    if (h_Input != 0 || v_Input != 0)
    {
        // 归一化方向,避免斜向输入时向量长度异常
        direction = new Vector3(h_Input, 0, v_Input).normalized;
        
        Quaternion rotationTarget = Quaternion.LookRotation(direction, Vector3.up);
        // 用RotateTowards实现固定步长旋转,替代Lerp的渐进减速
        rb.MoveRotation(Quaternion.RotateTowards(rb.rotation, rotationTarget, rotateSpeed * Time.fixedDeltaTime));
       
        rb.MovePosition(rb.position + transform.TransformDirection(Vector3.forward) * moveSpeed * Time.fixedDeltaTime);
    }
    else
    {
        // 无输入时锁定当前旋转,并清除角速度
        rb.MoveRotation(rb.rotation);
        rb.angularVelocity = Vector3.zero;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:23:13