物理问题的故障排除

使用物理引擎时,你可能会遇到一些意想不到的问题。

虽然其中许多问题可以通过配置解决,但其中一些问题是引擎错误造成的。有关物理引擎相关的已知问题,请参阅 GitHub 上开放的物理相关问题 。查看 已关闭的问题 也可以帮助回答与物理引擎行为相关的问题。

高速运动的对象会互相穿透

这被称为 隧道效应。在 RigidBody 中启用 连续碰撞检测模式 属性有时可以解决此问题。如果此方法无效,你可以尝试其他解决方案:

  • 使你的静态碰撞形状更厚。例如,如果你有一个玩家无法以某种方式穿过的薄地板,你可以使碰撞器比地板看起来更厚。

  • 根据你的快速移动物体的运动速度调整其碰撞形状。物体移动得越快,碰撞形状应该越向外扩展,以确保它能够更可靠地与薄墙发生碰撞。

  • 在项目设置中增加每秒物理周期数。虽然这有其他好处(例如更稳定的模拟和减少输入延迟),但这会增加 CPU 的使用率,可能不适用于移动或网页平台。对于大多数显示器来说,应该优先选择默认值 60 的倍数(如 120180240),以获得平滑的外观。

堆叠的对象摇摆不定

尽管看起来像一个简单问题,但是在物理引擎中带有堆叠物体的稳定刚体模拟很难实现。这是因为力结合后的相互作用。堆叠的物体越多,相互之间的作用力越强。这最终导致了模拟变得不稳定,使得物体不能相互堆叠在一起而不发生移动。

提升物理模拟频率可以帮助减少这个问题。为了这么做,增加项目设置中的 每秒物理周期数 选项。请注意,这会增加 CPU 的使用率,可能不适用于移动或网页平台。对于大多数显示器来说,应该优先选择默认值 60 的倍数(如 120180240),以获得平滑的外观。

缩放后的物理体或碰撞形状无法正确碰撞

Godot 当前没有支持缩放物理体或碰撞形状。作为替代方案,改变碰撞形状的范围而不是其缩放比例。如果你想让视觉表现的尺寸也发生变化,可以改变底层视觉表现(Sprite2D、MeshInstance3D……)并单独改变它的碰撞形状的范围。在这种情况下,请确保碰撞形状不是视觉表现节点的子节点。

由于资源默认是共享的,如果你不想让更改应用于场景中使用相同碰撞形状资源的所有节点,你需要让这个碰撞形状资源变得独一无二。这可以通过在碰撞形状资源的脚本中调用 duplicate() 方法来实现,然后在改变其尺寸之前进行操作。这样,更改将只影响当前的资源实例,而不会影响其他使用相同资源的节点。

当薄物体放在地板上时,它们会显得不稳定

可能是由以下两个原因之一造成的:

  • 地板的碰撞形状太薄了。

  • 刚体的碰撞形状太薄了。

在第一个场景中,这可以通过加厚地板的碰撞形状来缓解。例如,如果你有一个玩家不能以某种方式穿过的地板,你可以通过使碰撞器比地板看起来还要厚来解决。

在第二个场景中,常常只能通过提高物理仿真比率来解决(因为使形状更厚会导致刚体的视觉表现与其碰撞效果之间出现脱节)。

在这两种情况下,提高物理仿真的速率也可以帮助缓解这个问题。为此,可以在项目设置中增加**每秒物理周期数**。请注意,这会增加CPU的使用率,可能不适用于移动或网页平台。对于大多数显示器来说,应该优先选择默认值60的倍数(如120、180或240),以获得平滑的外观。

圆柱碰撞形状不稳定

在从Bullet到Godot 4中的GodotPhysics的过渡期间,圆柱体碰撞形状不得不从头开始重新实现。然而,圆柱体碰撞形状是最难支持的形状之一,这就是为什么许多其他物理引擎不提供对它们的支持。目前已知圆柱体碰撞形状存在一些问题。

我们建议目前使用盒或胶囊形状的碰撞体来模拟角色。盒形状通常提供最佳的可靠性,但缺点是使角色在对角线上占用更多的空间。胶囊碰撞形状没有这个缺点,但它们的形状可能会使精确的平台跳跃更加困难。

VehicleBody 仿真不稳定,尤其是在速度较大的时候

当一个物理体以高速移动时,它在每一个物理步骤中移动很长的一段距离。例如,当在 3D 中使用1单位等于1米的的标准时,一个以360 km/h速度移动的物体将会在每秒内移动100个单位长度。使用默认的物理仿真频率 60 Hz时,该物体每个物理周期移动 ~1.67个单位长度。这意味着小物体可能被物体完全忽略(由于隧道效应),同时这也意味着在如此高的速度下,仿真本身通常只有很少的数据可供处理。

快速移动的物体可以从被增加的物理仿真频率中得到很多好处。为了这么做,在项目设置中调高 每秒物理周期数。请注意,这会提高CPU的使用率而且可能在移动或web平台上不适用。对于大多数显示器来说,应该优先选择默认值60的倍数(如120、180或240),以获得平滑的外观。

当一个物体在瓦片上移动时,碰撞可能会导致颠簸

在物理引擎中,这里有一个因为物体在形状的边缘发生碰撞导致的已知问题,即使这条边被其它形状覆盖。这可以在2D和3D中触发。

解决该问题最好的代替方案是创建一个“复合”碰撞体。这意味着不使用带有自己碰撞体的独立图块,而是创建一个单独的碰撞形状代表一组图块的碰撞体。通常,你应该按照岛屿基础来分割复合碰撞器(这意味着每组相连的瓦片都有自己的碰撞器)。

在某些情况下,使用一个复合碰撞体也可以提升物理仿真性能。然而,由于复合碰撞体要复杂的多,这也许并不是在所有情况下都是对总体性能的提升。

当一个对象接触另一个对象时,帧率会下降

这很可能是因为其中一个物体使用的碰撞形状过于复杂。出于性能原因,凸形碰撞形状应该尽可能使用最少数量的形状。当依赖于Godot的自动生成时,可能会为单个凸形碰撞资源创建数十甚至数百个形状。

在一些场景中,用一组基础的碰撞形状(盒,球体或胶囊)替换一个凸形碰撞器可能带来更好的性能。

这个问题也可能发生在使用非常详细的三角网格(凹形)碰撞的静态刚体(StaticBodies)上。在这种情况下,使用简化的几何表示作为碰撞器。这不仅可以显著提高物理模拟的性能,还可以通过让你移除小的固定装置和缝隙,从而不被碰撞考虑,来提高稳定性。

物理仿真在远离世界原点的地方是不可靠的

这是由浮点数的精度误差引起的,当距离世界原点越远时,误差越明显。这个问题也影响渲染,当远离世界原点时可能会导致相机移动使摇晃。有关更多信息,参见 大世界坐标