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

Unity浮力项目中物体在水中稳定时出现剧烈抖动是什么原因?

浮力稳定时剧烈抖动的原因及解决方案

问题根因

  • 物理逻辑执行时机不同步:浮心计算逻辑GetUnderwaterCenter()放在渲染帧Update中执行,而浮力施加在物理帧FixedUpdate中执行,二者刷新频率不一致,导致浮心点位更新和力的施加不同步,触发抖动。
  • 浮力计算逻辑粗糙:当前只要浮点在水下就施加固定大小的浮力,没有结合浸入深度做平滑计算,当物体接近平衡位置时,浮力和重力的差值会跳变,形成往复震荡。这也是你调整drag参数无效的核心原因:刚体自带drag是全局线性阻力,抖动根源是力的跳变而非阻力不足。
  • 缺少角运动阻尼:当前仅对线性速度做了粘度阻力抑制,没有对角速度添加阻尼,角运动的抖动会传导到整体运动上。
  • 水面边界判定无容错:直接用y <= 0作为水下判定条件,浮点数精度误差会导致刚好在水面的浮点反复切换“在水/不在水”状态,浮心点位跳变带动力的跳变。

修复方案

代码修改示例

public class Buoyancy : MonoBehaviour
{
    // Variables
    public float buoyancy, viscosity;
    public float angularViscosity = 0.5f; // 新增角粘度参数
    public float waterLevel = 0f;
    public float waterThickness = 0.02f; // 新增边界判定死区

    public Transform[] floatPoints;

    Rigidbody objRb;

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

    private void FixedUpdate()
    {
        // 物理计算全部放在FixedUpdate中执行,保证同步
        List<Vector3> underwaterPoints = new List<Vector3>();

        for (int i = 0; i < floatPoints.Length; i++)
        {
            float pointY = floatPoints[i].position.y;
            // 加入死区判定,避免边界跳变
            if (pointY <= waterLevel + waterThickness)
            {
                underwaterPoints.Add(floatPoints[i].position);
                // 计算浸入深度,越深入浮力越大,力的变化更平滑
                float immersedDepth = Mathf.Max(0f, waterLevel - pointY);
                // 每个浮点单独施加对应深度的浮力,比统一加中心力更稳定
                objRb.AddForceAtPosition(Vector3.up * buoyancy * immersedDepth, floatPoints[i].position);
            }
        }

        if (underwaterPoints.Count > 0)
        {
            // 线性阻力
            objRb.AddForce(-objRb.velocity * viscosity);
            // 新增角阻力,抑制角抖动
            objRb.AddTorque(-objRb.angularVelocity * viscosity * angularViscosity);
        }
    }
}

额外调优建议

  • 适当增加浮点数量,浮点分布越均匀,浮力计算越稳定
  • buoyancy参数建议和刚体质量正相关,可参考设置为buoyancy = 9.81f * objRb.mass / floatPoints.Length,更接近真实浮力公式
  • 如果仍有轻微抖动,可以适当调高物理帧精度(路径:Edit->Project Settings->Time->Fixed Timestep,默认值0.02,可调整为0.01)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:54:01