实体系统中的碰撞检测和响应


12

ES带来更多乐趣...

目前,我有一些系统:

  • 渲染器(Renderable属性,Transform属性)
  • 运动(可移动属性,变换属性,可渲染属性(用于边界框等))
  • 输入(InputReceiver属性)
  • 等等

我要添加碰撞检测。我的第一个想法是添加一个执行碰撞的新系统。这对我来说很有意义,以防止这种分离的Motion系统,因为不是所有的东西,移动,或者动画不一定参与碰撞检测-摄像机,雾等-但似乎CollisionMotion相互依存。

Motion移动实体,变换需要与被验证Collision,且移动或者取消,或调节(弹跳,停在一个壁等)。

一种替代方法是创建一个Collidable属性,该属性维护对碰撞对象(kd-tree,八叉树等)的引用,该引用在可以相互碰撞的实体之间共享。然后,Motion系统将检查该属性,并使用它来检查或调整移动。

从代码角度来看,这是一个可以接受的解决方案。但是,从ECS架构的角度来看,似乎是将逻辑推入Motion系统中,而该逻辑不适用于具有Movable属性的所有实体。

我还可以在Movable属性中存储一个运动矢量,并使Collider系统Transform根据需要进行调整,但这将涉及在Motion和之间复制功能Collider,或者从ColliderMotion进行回调,并提供一些有关碰撞位置和曲面数据的反弹/反射等信息。 。

这可能属于“特殊情况破解”的标题,但是我想从以前处理过此问题的人员那里得到一些输入而无需创建大量的边缘案例代码。

问题 当运动系统和碰撞系统似乎需要彼此了解时,如何避免它们之间的紧密耦合?


1
有什么问题
jcora 2012年

@Bane在哪里放置碰撞检测逻辑,使碰撞+运动尽可能地分开并使系统之间的相互依赖性保持最小是个好地方。我的帖子有些
混乱

1
太好了,现在以粗体显示您的问题。:)
jcora 2012年

Answers:


7

您想得太多了。在我的引擎(也使用实体组件系统)中,每个引擎GameObject都有一个指向的指针ModuleCollision

游戏更新时会发生什么:

  • 场景将更新它包含的所有对象。它Update为每个调用函数GameObject
  • Update函数内部,每个函数GameObject 更新其速度和方向,而不更新其位置。
  • GameObject将其当前位置,速度和方向上传到ModuleCollision,如果有的话。
  • 场景会ModuleCollision根据碰撞进行检查。
  • 场景UpdatePost在每个上调用函数GameObject。如果对象具有碰撞模块,它将从碰撞模块获取更新的位置,速度和方向。位置随速度和方向更新。
  • GameObject构造将根据其位置和方向构造一个最终的3x3矩阵。

是的,状态有些重复,但这没关系。在a上进行碰撞处理ModuleCollision是最好的方法,因为否则,您将不得不检查每个对象GameObject以查看其是否具有ModuleCollision手柄。


2
因此,您不必担心发生碰撞时的回溯位置,而是将速度/加速度与平移分开,根据检测到的任何碰撞来更改速度/加速度,然后将这些更改传播到同一帧内的第二次专门更新中?看起来很干净。谢谢。
3Dave 2012年

3

我会这样

有三个系统:

  1. 运动系统
  2. 加速系统
  3. 碰撞系统

运动系统将速度应用于位置。加速系统将力施加到速度上。碰撞系统会检测碰撞并在正确的方向上施加力,或者,如果您要进行粗碰撞,则可以直接改变速度。

例如,您可以使用atan2计算碰撞之间的角度,然后使用该角度来施加正确的物体力/速度。

如果需要,也让碰撞检测系统广播消息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.