Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

3D粒子碰撞

粒子碰撞

由于 GPU 粒子完全在 GPU 中处理,所以它们无法访问游戏中的物理世界。如果你需要粒子与环境碰撞,你必须设置粒子碰撞节点。共有四种:GPUParticlesCollisionBox3DGPUParticlesCollisionSphere3DGPUParticlesCollisionSDF3DGPUParticlesCollisionHeightField3D

通用属性

常用粒子碰撞属性

常用碰撞属性

有一些属性你可以在所有碰撞节点中找到。它们位于检查器的 GPUParticlesCollision3D 区域中。

Cull Mask 属性根据每个系统的 visibility layers 控制哪些粒子系统会受到碰撞节点的影响。仅当碰撞器的剔除遮罩中至少启用了一个系统的可见性层时,粒子系统才会与碰撞节点发生碰撞。

警告

Godot 4.0 中有一个与 GPU 粒子碰撞有关的 已知问题 这将阻止剔除遮罩正常工作。我们将在该问题被修复时更新文档。

盒型碰撞

粒子碰撞盒

节点列表中的盒型碰撞

盒子碰撞节点的形状像一个实心的矩形盒子。你可以使用 Extents 属性控制它们的大小。盒子范围始终测量其边界边的一半,因此值 (X=1.0,Y=1.0,Z=1.0) 将创建一个每边宽 2 米的盒子。箱体碰撞节点可用于模拟粒子应碰撞的地板和墙壁几何形状。

要创建盒型碰撞节点,请在场景中添加一个新的子节点,并在可选节点列表中选择 GPUParticlesCollisionBox3D。如果想要更多动态效果,你可以将节点位置动画化,或将它附加到其他移动节点上。

粒子系统的盒型碰撞

两个粒子系统与盒型碰撞节点碰撞

球形碰撞

粒子碰撞球

节点列表中的球面碰撞

球形碰撞节点的形状类似于一个实心球体。半径 Radius``属性控制球体的大小。盒型碰撞节点不一定是完美的立方体,但是球形碰撞节点始终是球体。如果要独立于高度设置宽度,则必须更改 3D节点``Node3D``部件中的缩放``Scale 属性。

要创建球体碰撞节点,添加一个新的子节点到你的场景,并从可用节点列表中选择 GPUParticlesCollisionSphere3D。可以动画化球体的位置或将其附加到一个移动的节点,以获得更加动态的效果。

粒子系统中的球面碰撞

两个粒子系统与球型碰撞节点碰撞

高度场碰撞

粒子碰撞高度场

节点列表中的高度场碰撞

高度场粒子碰撞对于参与粒子碰撞的大型室外区域非常有用。在运行时,节点会根据范围内的所有不被遮罩剔除的网格,创建一个高度场。粒子会与该高度场所代表的网格发生碰撞。由于高度场是动态生成的,因此它可以跟随玩家的摄像机移动,并对关卡中的变化做出反应。如果改变高度场的密度参数,性能也会有很大的调整。

要创建高度场碰撞节点,添加一个新的子节点到你的场景,并从可用节点列表中选择 GPUParticlesCollisionHeightField3D

高度场碰撞节点的形状像一个盒子。外延``Extents``属性控制其大小。外延属性总是测量其边界边长的一半,因此``(X=1.0,Y=1.0,Z=1.0)``的值会创建一个边长 2 米的盒子。在创建高度场时,会忽略外延以外的任何内容。

Resolution 属性控制高度场的详细程度。较低的分辨率会以牺牲准确性为代价提高执行速度。如果高度场分辨率太低,则可能看起来像粒子穿透关卡几何体或在碰撞事件期间卡在空中。它们还可能完全忽略一些较小的网格。

高度场分辨率

在低分辨率下,高度场碰撞会错过一些更精细的细节(左图)

更新模式``Update Mode``属性可以控制何时根据其范围内的网格重新创建高度场。将其设置为移动时``When Moved`` 可使其仅在移动时刷新。这种模式性能良好,适合不经常变化的静态场景。如果需要粒子与位置经常变化的动态物体碰撞,可以选择 "Always"(始终),使其每帧都刷新。这样做会影响性能,建议只在必要时使用。

备注

重要的是要记住,当更新模式``Update Mode`` 设置为 移动时``When Moved`` 时,是*高度场节点*的移动触发了更新。当场内的某个网格移动时,高度场不会更新。

启用跟随摄像机``Follow Camera Enabled``属性后,高度场将跟随当前摄像机。只要摄像机移动,它就会更新。该属性可用于确保玩家周围始终存在粒子碰撞,同时不会在视线之外或太远的区域浪费性能。

带符号距离场(SDF)碰撞

粒子碰撞带符号距离场(SDF)

节点列表中的 SDF 碰撞

SDF 碰撞节点会创建一个粒子可以碰撞的带符号距离场。SDF 碰撞与高度场碰撞类似,都是将其范围内的多个网格转化单一粒子碰撞体积。主要区别在于带符号的距离场可以表示孔洞、隧道和悬臂,而这是高度场无法做到的。与高度场相比,带符号距离场的性能开销较大,因此最适合中小型环境。

要创建 SDF 碰撞节点,添加一个新的子节点到你的场景,并从可用节点列表中选择 GPUParticlesCollisionSDF3D。SDF 碰撞节点必须经过烘焙才能对关卡中的粒子产生任何影响。为此,请在选中 SDF 碰撞节点时点击视口工具栏中的烘焙 SDF 按钮,然后选择一个目录来存储烘焙数据。由于 SDF 碰撞需要在编辑器中烘焙,因此它是静态的,无法在运行时更改。

SDF 粒子碰撞

SDF 粒子碰撞允许实现非常精细的三维碰撞形状

SDF 碰撞节点的形状像一个盒子。Extents 属性控制其大小。范围始终测量其边界边的一半,因此值 (X=1.0,Y=1.0,Z=1.0) 会创建一个各边宽 2 米的盒子。节点范围之外的任何内容在碰撞时都将被忽略。

Resolution 属性控制距离场的详细程度。较低的分辨率会以牺牲准确性为代价提高运行速度。如果分辨率太低,粒子可能看起来像是穿透了关卡几何体或在碰撞事件期间卡在空中。它们还可能完全忽略一些较小的网格。

分辨率比较

不同分辨率的带符号距离场覆盖会覆盖一片相同区域:16(左)和 256(右)

厚度``Thickness``属性赋予距离场(通常内部是空心的)一定的厚度,以防止粒子高速穿透。如果发现有些粒子没有与场景中的几何体发生碰撞,而是直接穿透了它们,请尝试将此属性设置为更高的值。

烘焙遮罩``Bake Mask``属性控制烘焙带符号距离场时将考虑哪些网格。只有在烘焙遮罩的活动图层上渲染的网格才会参与粒子碰撞。

故障排除

为了使粒子碰撞起作用,粒子的可见性 AABB 必须与碰撞器的 AABB 重叠。如果尽管设置了碰撞器,但碰撞似乎不起作用,请通过选择 GPUParticles3D 节点并在 3D 编辑器视口顶部选择 GPUParticles3D > 生成可见性 AABB… 来生成更新后的可见性 AABB。

如果粒子移动得很快而碰撞体很薄,有两种解决方案:

  • 让碰撞体变得更厚。例如,如果粒子不能穿过一个坚实的地面,你可以让代表地面的碰撞体比其实际的视觉表现更厚。高度图碰撞体(heightfield collider)在设计上自动处理这种情况,因为高度图无法表示“房间之上还有房间”的碰撞情况。

  • 增大 GPUParticles3D 节点中 Fixed FPS 的值,以增加粒子碰撞检测的频率。这会产生性能影响,所以应避免设置过大的值。