BEPUphysicsint碰撞事件详解

发布时间 2023-10-27 11:21:39作者: 游戏开发阿博

上一节我们給大家介绍了BEPUphysicsint的基本使用,在游戏开发中我们经常要使用物理引擎的事件,所以本节我们详细的讲解BEPUphysicsint 的物理事件。此物理引擎会产生了碰撞事件与非碰撞事件,碰撞事件大家好理解,非碰撞事件例如: 物理Entity的update事件,Entity的activation/deactivation事件等。本文主要详解由物理碰撞所导致的事件。

 

如何获取物理事件

 

接下来分析一下如何获得物理事件的delegate。每个可碰撞的物理Entity的有一个Collidable 对象,通过访问它的CollisionInformation属性就能获取得到,每个Collidable 都有一个自己的ContactEventManager, 通过访问Events 的每个Event的属性,就可以往里面添加回调函数,就可以获得该事件。所以获取物理事件的delegate: entity. CollisionInformation.Events.xxxxx事件。这样添加一个物理事件,我们可以做如下操作:

 

当物理引擎有物理事件发生的时候,就会触发回调到你对应的设置函数。

 

碰撞事件的类型

 

在物理Entity的ContactEventManager种我们可以找到所有的事件与事件类型,接下来详细讲解几组关键的物理碰撞相关的事件类型。

 

及时事件与延时事件

我在物理引擎中会有两类事件,一类是及时事件(ing,正在进行时),一类是延时事件(ed,过去式)。上面我们列举出来的事件都式延时事件,例如: ContactRemoved 每个后缀都是ed结束,表示延时事件。与之相对应的还有正在发生的事件(ing, 正在进行时),比如:PairRemoved /RemovingPair,这两个事件的区别在于一个是延时事件,一个是正在进行时事件。

 

在事件回调中安全的处理事件

 

物理事件的回调函数,都是物理引擎执行中回调的,有可能有些操作会改变物理引擎运行环境的Context,导致不安全的操作与异常,如何在回调函数中正确的安全的处理呢?

对于延迟事件,是在处理完所有的物理计算后,再来进行延迟事件处理的,所以相对来说还是安全的。这里你要注意一点,就是在延迟事件处理函数中的数据对象,有可能会在调用完事件函数后回收这些数据对象,所以你自己收集这些数据对象的时候要小心,小心物理引擎内部把传过来的事件对象数据給回收掉。

及时事件,相对于延时事件来说安全性就要小很多,因为它是物理引擎计算过程中调用的。正式由于它们是物理引擎迭代计算交互时调用,所以你可以拦截与修改物理交互。如果引擎使用多线程,即从工作线程(相比物理引擎主线程的另外一个线程)来调用物理引擎的及时事件,就要注意线程处理的上下文。及时事件的处理在回调函数内一次性解决,不应该保留到事件处理函数之外。

 

复合体的事件处理

在BEPU物理引擎中还有复合体(Compound Bodies)的概念,复合体为碰撞的子实体组成,子实体中有可以为子复合体,这样,就形成了一个复合体的树。复合体本身是没有物理几何学,它的非复合子对象是它的物理几何体。

在Compound Body中收集每个孩子的碰撞检测的事件是很不方便的,为了方便处理Compound Body收集孩子的物理事件后,触发到它的事件上。

 

今天的分享就到这里了,关注我们,持续的学习BEPUphysint3D物理引擎实战系列。

 

下节预告: 基于BEPUphysicsint整合到Unity项目实战