上一节我们給大家介绍了BEPUphysicsint的基本使用,在游戏开发中我们经常要使用物理引擎的事件,所以本节我们详细的讲解BEPUphysicsint 的物理事件。此物理引擎会产生了碰撞事件与非碰撞事件,碰撞事件大家好理解,非碰撞事件例如: 物理Entity的update事件,Entity的activation/deactivation事件等。本文主要详解由物理碰撞所导致的事件。
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。
如何获取物理事件
接下来分析一下如何获得物理事件的delegate。每个可碰撞的物理Entity的有一个Collidable 对象,通过访问它的CollisionInformation属性就能获取得到,每个Collidable 都有一个自己的ContactEventManager, 通过访问Events 的每个Event的属性,就可以往里面添加回调函数,就可以获得该事件。所以获取物理事件的delegate: entity. CollisionInformation.Events.xxxxx事件。这样添加一个物理事件,我们可以做如下操作:
(1) 创建一个回调函数,回调函数的参数格式与物理事件Events中的delegate描述一致;
(2) 将这个回调函数,加入到对应物理事件Event的delegate中。
当物理引擎有物理事件发生的时候,就会触发回调到你对应的设置函数。
碰撞事件的类型
在物理Entity的ContactEventManager种我们可以找到所有的事件与事件类型,接下来详细讲解几组关键的物理碰撞相关的事件类型。
PairCreated: 当两个物理的Entity发生了边界重叠时触发;
PairRemoved: 当两个物理的Entity边界结束重叠时触发;
ContactCreated: 当两个物理Entity碰撞的时候,在Contact List的中的碰撞点信息有增加时触发;
InitialCollisionDetected: 当物理Entity的碰撞列表发生改变的时候调用,比如没有碰撞物体了,比如加了一个新的碰撞物体进来等。
ContactRemoved: 当两个物理Entity碰撞的时候,在Contact List的中的碰撞点信息有移除时触发;
CollisionEnded: 当两个物理Entity碰撞信息Contact List变为0的时候触发;
及时事件与延时事件
我在物理引擎中会有两类事件,一类是及时事件(ing,正在进行时),一类是延时事件(ed,过去式)。上面我们列举出来的事件都式延时事件,例如: ContactRemoved 每个后缀都是ed结束,表示延时事件。与之相对应的还有正在发生的事件(ing, 正在进行时),比如:PairRemoved /RemovingPair,这两个事件的区别在于一个是延时事件,一个是正在进行时事件。
在事件回调中安全的处理事件
物理事件的回调函数,都是物理引擎执行中回调的,有可能有些操作会改变物理引擎运行环境的Context,导致不安全的操作与异常,如何在回调函数中正确的安全的处理呢?
对于延迟事件,是在处理完所有的物理计算后,再来进行延迟事件处理的,所以相对来说还是安全的。这里你要注意一点,就是在延迟事件处理函数中的数据对象,有可能会在调用完事件函数后回收这些数据对象,所以你自己收集这些数据对象的时候要小心,小心物理引擎内部把传过来的事件对象数据給回收掉。
及时事件,相对于延时事件来说安全性就要小很多,因为它是物理引擎计算过程中调用的。正式由于它们是物理引擎迭代计算交互时调用,所以你可以拦截与修改物理交互。如果引擎使用多线程,即从工作线程(相比物理引擎主线程的另外一个线程)来调用物理引擎的及时事件,就要注意线程处理的上下文。及时事件的处理在回调函数内一次性解决,不应该保留到事件处理函数之外。
复合体的事件处理
在BEPU物理引擎中还有复合体(Compound Bodies)的概念,复合体为碰撞的子实体组成,子实体中有可以为子复合体,这样,就形成了一个复合体的树。复合体本身是没有物理几何学,它的非复合子对象是它的物理几何体。
在Compound Body中收集每个孩子的碰撞检测的事件是很不方便的,为了方便处理Compound Body收集孩子的物理事件后,触发到它的事件上。
今天的分享就到这里了,关注我们,持续的学习BEPUphysint3D物理引擎实战系列。
下节预告: 基于BEPUphysicsint整合到Unity项目实战
网友评论