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

Unity中Rigidbody角色Y轴抖动问题解决(多平面地面场景)

解决Unity中多平面地面下Rigidbody角色Y轴抖动问题

问题分析

这种Y轴抖动是因为多个相邻平面的碰撞体接缝处,物理引擎计算碰撞时会出现微小位置偏差,当角色移动经过接缝时,Rigidbody会在不同平面间产生细微的上下跳动。

解决方案

以下是几种针对性的解决方法,按优先级推荐:

1. 消除地面碰撞体接缝间隙

不用合并成单个大平面,只需把相邻平面的碰撞体稍微重叠0.01-0.02单位,消除接缝处的物理检测间隙,避免引擎反复切换碰撞判定。
也可以用Unity自带的Mesh Combine工具,把多个地面网格合并为一个但保留原视觉分割,这样碰撞体是整体,同时不破坏场景布局。

2. 调整Rigidbody参数优化

  • 切换插值模式:当前用的是Interpolate,可以改成Extrapolate,让Rigidbody根据物理预测提前修正位置,减少抖动。
  • 增加Y轴阻尼:在FixedUpdate中给Y轴速度加微小阻尼,抑制无意义跳动,代码修改如下:
    private void FixedUpdate()
    {
        Vector3 movementForce = new Vector3(horizontalInput * moveSpeed * 2f, 0f, 0f);
        rb.AddForce(movementForce, ForceMode.Force);
        
        // 抑制Y轴抖动,系数可在0.9-0.95之间调整
        Vector3 vel = rb.velocity;
        vel.y *= 0.92f;
        rb.velocity = vel;
    }
    
  • 调高休眠阈值:在Inspector里找到Rigidbody的Sleep Threshold(默认0.005),调高到0.01,让角色低速时更快进入物理休眠,减少冗余计算。

3. 用射线检测手动控制接地状态

放弃完全依赖物理碰撞的Y轴位置,用射线检测判断角色是否接地,手动修正Y轴位置:

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 6f;
    public float groundCheckDistance = 0.12f; // 射线检测距离
    public LayerMask groundLayer; // 指定地面专属图层

    private Rigidbody rb;
    private float horizontalInput;
    private bool isGrounded;

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

    private void Update()
    {
        horizontalInput = Input.GetAxis("Horizontal");
        // 射线检测是否接地
        isGrounded = Physics.Raycast(transform.position, Vector3.down, groundCheckDistance, groundLayer);
    }

    private void FixedUpdate()
    {
        Vector3 movementForce = new Vector3(horizontalInput * moveSpeed * 2f, 0f, 0f);
        rb.AddForce(movementForce, ForceMode.Force);

        // 接地时手动固定Y轴位置
        if (isGrounded)
        {
            RaycastHit hit;
            if (Physics.Raycast(transform.position, Vector3.down, out hit, groundCheckDistance, groundLayer))
            {
                Vector3 pos = rb.position;
                pos.y = hit.point.y + GetComponent<Collider>().bounds.extents.y;
                rb.position = pos;
                // 重置Y轴速度
                rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
            }
        }
    }
}

注意:需给地面设置单独图层,在groundLayer中选择该图层,避免射线误检测其他物体。

4. 替换为CharacterController组件

如果角色不需要复杂物理交互,CharacterController本身针对角色移动做了优化,能自动处理地面接缝抖动,适合多数常规移动场景。


你的代码及设置翻译

原代码(中文注释版)

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 6f; // 角色移动速度

    private Rigidbody rb;
    private float horizontalInput;

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

    private void Update()
    {
        horizontalInput = Input.GetAxis("Horizontal"); // 获取水平方向输入
    }

    private void FixedUpdate()
    {
        // 计算移动力
        Vector3 movementForce = new Vector3(horizontalInput * moveSpeed * 2f, 0f, 0f);

        // 给角色刚体施加移动力
        rb.AddForce(movementForce, ForceMode.Force);
    }
}

Rigidbody设置(中文翻译)

质量 : 1
阻力 : 0
角阻力 : 0.05
启用重力 : 勾选
是否运动学 : 未勾选
插值模式 : 插值
碰撞检测模式 : 连续
冻结位置 : 全部未勾选
冻结旋转 : 全部勾选

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:45:16