一、新建第一人称蓝图项目。在场景中随意选择一个cube(simulate physics勾选),然后在level blueprint中添加 OnActorHit事件,打印事件,蓝图如下:
对应的Actor如下设置(项目默认,没做修改):
注意,此时Simulation Generates Hit Events没有勾选;运行程序后结果如期,子弹击中该Actor(Name:撞击时测试对象)触发OnActorHit事件;
二、再来测试勾选Simulation Generates Hit Events的效果。
此时运行后,在子弹没有击中时,也会产生一些hit事件,结果如下图:
三、总结:1)子弹击中的过程其实是一个kinematic(运动学)的模拟,而不是物理模拟,打开FirstPersonProjectile蓝图,可以看到如下设置:
运动学方式(官档所谓kinematic,所谓运动学是经典力学的一个分支,具体参考维基百科,即运动时不考虑物体的质量,惯性……之类)中改变物体(通常就是Actor,即Actor的RootComponent)的空间位置时,使用SetActorLocation或者通过组件设置运动速度(其实,最终结果也是使用SetActorLocation系列函数),指定Sweep有效(Enabled),如果与物体发生碰撞(collide)时,触发OnActorHit事件(或者OnComponentHit,如果是在组件级别上设置碰撞事件),与是否勾选Simulation Generates Hit Events 无关。这也就是所谓的Query方式。(后记,运动学方式大致算法是物理移动到一个指定位置时(使用SetActorLocation系列函数),不能盲目的移动到用户指定的位置,大致分成二个阶段:1,扫描(sweep),如果当前位置到目标位置之间有障碍(obstacle),则不能移动到目标位置,要判定碰撞发生时的位置和矢量……等一系列参数(想不出来更恰当的描述),这也是FHitResult之类的参数存在的意义,2、然后根据碰撞表(其实这一步我们可以控制,例如官网教程中控制pawn沿桌子边沿滑动的例子)进行响应。当然如果不发生上述事件(前进道路无障碍),则如用户意愿,把Actor移动到指定位置。
2)如果勾选Simulation Generates Hit Events,则如文档所述,利用PhysX(Nvidia PhysX SDK)进行物理的模拟,这没什么好讲的,主要是此时如果物体与别的物体发生接触(contact),就会触发这个事件。这个行为不是UE的,应该是PhysX模拟的结果,对于PhysX的研究,留待后续……,唔,10M的文档,想想头痛。
三、2017年3月20日进一步的测试与总结(cnblogs吃了我的文章,没心情写了,简单总结,有心情再细写):
OnComponentHit是事件的发起者,它调用NotifyActor,NotifyActor随之广播(broadcast)OnActorHit,所以这三个事件是一体俱荣的。另外,对于委托,一定要加UFUNCTION函数修饰符,不能在同一个地方再次栽跟头了,愚蠢……!
1、在打开物理模拟过程前提下(非kinematic),如果打开Simulation Generates Hit Events, 在模拟过程中,如果由于物理模拟产生了碰撞,就会触发上述三个事件。如果关闭Simulation Generates Hit Events,则不会触发上述三个事件。但是注意一定是由于物理模拟产生的碰撞。
2、对于kinematic方式,即关闭物理模拟时,Simulation Generates Hit Events不起任何作用,这点在文档中已经指出。
3、对于kinematic方式,上述三个事件,只受collision enabled中的Query选项是否打开影响,如果打开就会触发,否则不受影响。