# Unreal4碰撞检测

此文为Collision Filtering的原创翻译,本文内容版权归原文所有,仅供学习,如需转载望注本文地址,翻译不易,谢谢理解。

显然决定什么相互碰撞是很重要的,但它可能也很难处理,这是一个在我们研究UE4的时候花了很长时间来讨论的问题。我们起初拥有的系统可能稍微有些复杂,但它是很强大和一致的,所以我想展示一下我们是怎么做成现在这个样子的。我们讨论了不同的对策来应对碰撞,我们如何使用不同的channels来过滤碰撞,然后概括出简单和复杂的碰撞形状的不同。

# Blocking,Overlapping,Ignoring

第一件事情就是要知道应该在什么时候碰撞,你得决定物体是否穿过去还是要碰撞上。比如一堵砖墙会"Block"一个player,但是一个触发器会"Overlap"一个player,允许他们穿过。虽然"Block Hit"和"Overlap"在UE4中都会各自产生一个事件,但它们有很大的不同。比如对于"Block"来说,我们会实际停止寻找碰撞在物体第一次blocking碰撞体后,这对性能是很大的优化,想象你拿一把射程为1000米的枪去打你前方一米的墙,我们不用检测剩下999米了!其他物体会完全"Ignore"碰撞体,这是第三种碰撞反应类型。

# TraceChannels,ObjectChannels

接下来第二个关于碰撞过滤的核心问题是"要碰撞谁?",是物体来决定要查询什么样的碰撞类型?或者还是碰撞过滤的查询来决定要碰撞什么类型的物体,在不同的场景中他们都有意义,所以UE4都支持!

想像下我们在游戏中定义了两个"Trace Channels",一个是为了"可见性",另一个是为了"武器"查询。有一堵都会阻挡这两个通道的墙,一个只阻挡可见性却不阻挡武器的灌木丛,一个只阻挡武器却不阻挡可见性的防弹玻璃。当你做这种碰撞查询时你需要使用Single Trace Channel

TraceExample

假如当我们改变了Trace Channel对不同的物体的反应,或者加入了新的物体,那么游戏代码就必须要知道得查询什么类型的物体,在游戏中可能需要处理很多不同的类型!所以Trace Channel得允许我们从内容上对不同物体的反应进行修改,而不是改变调用代码(这可能会破坏其他的东西)。

有些场景中是需要你根据物体的类型来查询他们,这时我们就需要使用"Object Channels"。一个例子就是发生爆炸的时候,你想在一定半径范围内快速找到类型是"Pawn"或者"PhysicsBody"的所有物体。当你做这种类型查询时,你需要使用Multiple Object Channel

UE4有一些内置的Trace Channels(Visibility,Camera)和Object Channels(WorldStatic,WorldDynamic,Pawn,PhysicsBody,Vehicle,Destructible),你可以在 Edit -> Project Settings -> Collision中自定义自己的类型,但是总共不能超过32种。

# 移动物体间的碰撞

当处理移动物体间的碰撞时可能会稍微复杂点,因为会有不同情况的组合。在UE中每个物体都知道它自己所属的Object Channel,而且还有如何应对其他Object Channels的列表。当两个物体交互时,我们看他们应该如何反应时,采取两个都是block才block的策略,比如:

FilterTable

所以想象下面的场景:

ObjectExample

现在Player向前移动。首先他会overlap灌木丛,因为Player是Pawn类型,所以灌木丛会Overlap他,因为灌木丛是WorldStatic,Player想要block他,根据上面的表,最后的结果是overlap!相似的砖墙和Player都想block对方,所以player穿过灌木丛,触发overlap事件,但他被墙阻挡,触发一个hit事件。

EventType

如果你想让两个Player中的一个变成"幽灵",可以将他对Pawn通道的反映类型从Block变成Ignore,然后他就会穿过其他Players。

# 预设碰撞

虽然这个系统对你在关卡中将会碰撞的物体有很多控制,实际上很多物体都有常规设置。为了让这个更方便点,UE4有一个"Collision Preset"系统。每种预设包含一个物体类型,以及对每个Trace Channel和Object Channel的反应。当你选择关卡中的一个物体时,你就会看到一个简单的下拉菜单,让你选择一种预设。

CollisionPreset1

UE4有几种内置的预设(比如Invisible Wall, Physics Actor等等),你还可以创建自己的在Porject Setting里面。如果你不想使用预设,你可以选择"Custom...",然后就像我们上面所说的那样,你就可以改变针对不同通道的反应:

CollisionPreset2

# 简单和复杂的碰撞

最后要理解的事是UE4中的每个物体都有"复杂"和"简单"的碰撞代表。复杂的碰撞是使用实际的渲染外观图形来做碰撞,这对于武器的效果追踪很有用,你可以准确地射你看到的任何地方。但是你不会经常想让这个碰撞体起作用,所以每个mesh也都有一个简单的碰撞,它是spheres,boxs,capsules和凸多面体的集合。当你想执行一个碰撞检测的时候,你告诉UE4想碰撞哪种类型的图形。比如Player的移动,一般都是和简单碰撞体碰撞,来避免卡在一些小的细节上。

在编辑器中,有一个有用的View Mode可以让你看到一个Player会和场景世界中的哪些物体碰撞:

CollisionViewMode

DifferentCollisions