UE4 碰撞篇-打破砂锅问到底(4) 碰撞计算
发布网友
发布时间:2024-10-03 14:31
我来回答
共1个回答
热心网友
时间:2024-10-21 03:32
移动类型的碰撞检测使用的是PhysX的Sweep场景查询。当目标在移动过程中触发碰撞时,会引发OnHit事件和Overlap事件。跟踪代码是关键,首先查看调用堆栈,然后逐步分析。
在UE中,无论哪种移动方式,最终会调用一个类似的方法,它接受初始点和目标点作为参数。目标点是移动的目的地,这个方法用于检测目标点是否可达。接着在UWorld::ComponentSweepMulti中遍历关联的PhysX的pxShape执行sweep查询。
ExecuteOnPxRigidActorReadOnly是一个宏,内部执行传入的函数,该函数的参数是BodyInstance中获取的pxActor。之后通过FillInlinePxShapeArray_AssumesLocked获取到所有关联的pxShape执行GeomSweepMulti_PhysX。
首先准备查询参数,包括碰撞规则的pxFilterData、查询所需的回调函数PQueryCallbackSweep等作为参数,执行pxScene->sweep传递给物理引擎处理请求。这里关键在于回调函数,让虚幻实现自己的碰撞规则。
FPxQueryFilterCallbackSweep继承自FPxQueryFilterCallback,而PxQueryFilterCallback继承自PhysX中的结构体PxQueryFilterCallback并重载了preFilter和postFilter函数。根据PhysX的回调规则,判断preFilter返回的结果,如果为PxQueryHitType::eBLOCK则为block目标,如果为PxQueryHitType::eTOUCH则为overlap目标,如果为PxQueryHitType::eNONE则忽略目标。因此,重载的preFilter就是计算移动碰撞的地方。
在其中,CalcQueryHitType定义了碰撞规则的计算方式。最终明白虚幻的碰撞规则:如果两个对象都是block,碰撞结果为block;一个block、一个overlap,则碰撞结果为overlap;一个block与一个ignore,碰撞结果为ignore;两个都是overlap,则碰撞结果为overlap;只要有一个ignore,碰撞结果为ignore。
射线类型碰撞检测与移动碰撞类似,遵循相同的碰撞规则。首先从LineTraceSingle开始分析,将ETraceTypeQuery TraceChannel转换为ECollisionChanel,接着配置参数并调用RaycastSingle执行碰撞查询。
物理模拟类型碰撞检测同样遵循碰撞规则。在执行物理模拟时,系统会自动检测和处理碰撞事件,确保物理对象之间的正确交互。