碰撞检测备忘录
重点
碰撞结果的计算都可以根据该表进行.

前提
为什么我使用的LineTraceMulti只返回一个对象?
答案:
UKismetSystemLibrary.LineTraceMulti函数会返回所有它Overlap的对象,
并且在检测到第一个Block对象的时候停止.
1 | Multiline trace will return all objects that overlap, and will stop the trace when it sees at least one blocking hit. In your case you’ll probably want to use a channel other than visibility so that you can have objects that allow for bullet penetration to be marked as overlap instead of blocking. |
使用解析
思考一下下图, 后面都会围绕该如讲解.

可以将UE的碰撞检测类型分成三种:
基于TraceType的射线检测(注意, 该类型是)

基于ObjectType的射线检测

- 基于Profile的射线检测

基于TraceType的射线检测
1 | bool UKismetSystemLibrary::LineTraceSingle(const UObject* WorldContextObject, const FVector Start, const FVector End, ETraceTypeQuery TraceChannel, bool bTraceComplex, const TArray<AActor*>& ActorsToIgnore, EDrawDebugTrace::Type DrawDebugType, FHitResult& OutHit, bool bIgnoreSelf, FLinearColor TraceColor, FLinearColor TraceHitColor, float DrawTime) |
以LineTraceSingle为例,
其中使用了Trace的类型为ETraceTypeQuery,
然后UE会将其转换成ECollisionChannel,
最终调用UWorld.LineTraceSingleByChannel.
而ECollisionChannel具体类型为:

而ObjectType和TraceType的区分方式为:

所以,
在配置中定义的无论TraceChannels还是ObjectChannels,
其实都是ECollisionChannel.

重点: 可以将LineTrace理解为, 1对所有类型都Block, 那么Ignore/Overlap/Block与否, 取决于Component本身的Collision配置. 下图中Cube1配置的是Overlap, 则他们二者最终的结果就是Overlap.

即:

基于ObjectType的射线检测
同基于TraceType的射线检测, 这里就不赘述了.
基于Profile的射线检测
通过传入的Profile, 对场景中的物体进行碰撞检测.

例如在Profile(TestTraceMulti)中,
自身类型为1,
对WorldStatic的检测类型为Overlap.
而场景中物体对1的碰撞类型为Block,
则最终结果为Overlap


二者交互类型为Overlap.

总结
使用Profile相当于双向指定, 所以推荐新增类型都为ObjectType(LineTrace不能双向指定, 因为Profile类型只能指定为ObjectType). 双向指定可以得到更多可定制的情形, 可以更好的使用变化的场景.
附
将EObjectTypeQuery转换成ECollisionChannel.
1 | ECollisionChannel UEngineTypes::ConvertToCollisionChannel(EObjectTypeQuery ObjectType) |
将ETraceTypeQuery转换成ECollisionChannel.
1 | ECollisionChannel UEngineTypes::ConvertToCollisionChannel(ETraceTypeQuery TraceType) |
将ECollisionChannel转换成EObjectTypeQuery.
1 | EObjectTypeQuery UEngineTypes::ConvertToObjectType(ECollisionChannel CollisionChannel) |
将ECollisionChannel转换成ETraceTypeQuery.
1 | ETraceTypeQuery UEngineTypes::ConvertToTraceType(ECollisionChannel CollisionChannel) |