游戏开发中的物理之碰撞形状(3D)

2,085 阅读5分钟

这是我参与更文挑战的第26天,活动详情查看: 更文挑战

本指南说明:

Godot 中 3D 中可用的碰撞形状类型。

使用凸面或凹面网格作为碰撞形状。

关于 3D 碰撞的性能注意事项。

Godot 提供了多种碰撞形状,具有不同的性能和准确性权衡。

您可以通过添加一个或多个 CollisionShapes作为子节点来定义PhysicsBody的形状。请注意,您必须将Shape资源添加到 Inspector 停靠栏中的碰撞形状节点。

笔记

当您将多个碰撞形状添加到单个 PhysicsBody 时,您不必担心它们会重叠。它们不会相互“碰撞”。

原始碰撞形状

Godot 提供了以下原始碰撞形状类型:

  • 箱形
  • 球体形状
  • 胶囊形状
  • 圆柱体形状。它仅在使用 Bullet 物理引擎时可用。

您可以使用一个或多个原始形状来表示大多数较小对象的碰撞。但是,对于更复杂的对象,例如大船或整个关卡,您可能需要使用凸面或凹面形状。更多关于下面的内容。

我们建议对 RigidBodies 和 KinematicBodies 等动态对象使用原始形状,因为它们的行为最可靠。它们通常也提供更好的性能。

凸碰撞形状

凸碰撞形状是原始碰撞形状和凹碰撞形状之间的折衷。它们可以表示任何复杂的形状,但有一个重要的警告。顾名思义,单个形状只能表示凸形。例如,金字塔是凸的,而空心的盒子是凹的。要定义具有单个碰撞形状的凹面对象,您需要使用凹面碰撞形状。

根据对象的复杂性,您可以通过使用多个凸面形状而不是凹面碰撞形状来获得更好的性能。Godot 允许您使用 凸分解来生成与空心对象大致匹配的凸形状。请注意,这种性能优势在一定数量的凸面形状后不再适用。对于大型复杂对象,例如整个关卡,我们建议改用凹形。

通过选择 MeshInstance 并使用3D 视口顶部的Mesh菜单,您可以从编辑器生成一个或多个凸面碰撞形状。编辑器公开了两种生成模式:

  • 创建单凸面碰撞兄弟使用 Quickhull 算法。它使用自动生成的凸碰撞形状创建一个 CollisionShape 节点。由于它只生成单一形状,因此它提供了良好的性能,非常适合小物体。

  • Create Multiple Convex Collision Siblings使用 V-HACD 算法。它创建了几个 CollisionShape 节点,每个节点都有一个凸面形状。由于它生成多种形状,因此以性能为代价对凹面物体更准确。对于中等复杂度的对象,它可能比使用单个凹面碰撞形状更快。

凹面或三边形碰撞形状

凹面碰撞形状,也称为三边形碰撞形状,可以采用任何形式,从几个三角形到数千个三角形。凹形是最慢的选项,但在 Godot 中也是最准确的。您只能在 StaticBodies 中使用凹面形状。除非刚体的模式为静态,否则它们不能与 KinematicBodies 或 RigidBody 一起使用。

笔记

尽管凹面形状提供了最准确的碰撞,但接触报告可能不如原始形状精确。

当不使用 GridMaps 进行关卡设计时,凹形是关卡碰撞的最佳方法。也就是说,如果您的关卡有小细节,您可能希望将这些细节从碰撞中排除,以提高性能和游戏体验。为此,您可以在 3D 建模器中构建一个简化的碰撞网格,并让 Godot 自动为其生成碰撞形状。更多关于下面

请注意,与原始形状和凸面形状不同,凹面碰撞形状没有实际的“体积”。您可以在形状的外部和内部放置对象。

您可以通过选择 MeshInstance 并使用3D 视口顶部的Mesh菜单从编辑器生成凹面碰撞形状。编辑器公开了两个选项:

  • Create Trimesh Static Body是一个方便的选项。它创建一个包含与网格几何体相匹配的凹形的 StaticBody。

  • Create Trimesh Collision Sibling创建一个 CollisionShape 节点,其凹面形状与网格的几何形状相匹配。

笔记

假设您需要在凹形碰撞形状上制作 RigidBody滑动。在这种情况下,您可能会注意到,有时,刚体会向上颠簸。要解决此问题,请打开Project > Project Settings并启用 Physics > 3d > Smooth Trimesh Collision。

启用平滑的trimesh 碰撞后,请确保凹面形状是StaticBody 的唯一形状,并且它位于原点而没有任何旋转。这样,刚体应该在静态体上完美滑动。

也可以看看

Godot 可以为您导入的 3D 场景自动生成碰撞形状。有关更多信息,请参阅文档中的导入提示。

性能警告

您不仅限于每个 PhysicsBody 的单个碰撞形状。尽管如此,我们还是建议保持尽可能少的形状数量以提高性能,尤其是对于 RigidBodies 和 KinematicBodies 等动态对象。最重要的是,避免平移、旋转或缩放 CollisionShapes 以从物理引擎的内部优化中受益。

在 StaticBody 中使用单个未转换的碰撞形状时,引擎的宽相位算法可以丢弃不活动的 PhysicsBodies。在狭窄的阶段,然后将只需要考虑到活跃的机构的形状。如果一个 StaticBody 有很多碰撞形状,broad 阶段就会失败。较慢的窄阶段必须对每个形状执行碰撞检查。

如果遇到性能问题,您可能必须在准确性方面进行权衡。大多数游戏都没有 100% 准确的碰撞。他们找到了创造性的方法来隐藏它或以其他方式使其在正常游戏过程中不显眼。


如果你真的从这篇文章中学到了一些新东西,喜欢它,收藏它并与你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦