UE4 学习笔记 (二) 记一次物理碰撞无法生效的解决
引擎中的物理碰撞检测是我们开发过程中常用的一个功能,最近在学习UE4的过程中尝试初步学习了这部分的模块。遇到Collision无法生效的问题,在这里记录汇总顺便分享下。
在UE4下发生碰撞,需要满足如下两个条件:
- 碰撞网格: 注意这里是碰撞网格,不是普通的Mesh。一般来说由美术从3D软件中导出FBX时同时携带Convex Collision信息或者从在UE中手动添加。注意:后面我在这里踩了一个坑!
- 碰撞组件: 这个一般都不会忘记, 我们在添加StaticMesh对象的时候会默认挂载上Collision组件。
讲完先决条件,我们来看下发生碰撞一般会需要注意的点:
1. 配置Collision Presets:
一般来说默认配置就可以,如果手动配置过,你应该大概知道这几种区别
Actor A | Actor B | 结果 |
---|---|---|
Ignore | 任何 | 物体A、B会相互穿过彼此,不会有任何碰撞事件发生 |
Overlap | Overlap 或 Block | 物体A、B会穿过彼此,overlap事件会发送给双方 |
Block | Block | 双方会被Block住无法移动,并都收到碰撞事件 |
2. 检查Collision组件的位置:
一个Actor如果Collision主键没有挂载在根节点上,那么他可以作为被碰撞体Block其他物体。但是如果移动该Actor主动和别的物体碰撞,他将不会收到碰撞信息。
这里我们一般只需要把StaticMesh拖动到根节点上:
如果上面的几部你都配置对了,但是依然没有碰撞产生。那看下最后一条!我也被这个问题Block了几个小时😢
3. 检查物体的Covex Collision:
文章开始就讲了两个先决条件的第一条,仔细检查下你的mesh文件的Convex Collision是否存在。双击mesh文件,看下这里:
如果这里数组为空就要注意啦,说明这个模型自身不带Convex Collision信息,在Collision/Convert Boxes to Convex中手动添加一个并保存。
结论
说下这次碰到问题的解决过程:
首先在上述步骤1、2都反复检查很久之后依然发现无法产生碰撞。既然UE是有源码的,那就开始进去调试下吧(想到用Unity时候只能继续猜了😭),对比下正常能碰撞的工程。 发现大致如下的差异:
如果物体不能碰撞,那移动过程中就不会被阻止。大致猜测UE中物体移动的几个接口,大致断点到在UPrimitiveComponent::MoveComponentImpl函数里进行移动的计算:
1 | bool const bHadBlockingHit = MyWorld->ComponentSweepMulti(Hits, this, TraceStart, TraceEnd, InitialRotationQuat, Params); |
在动的过程中会通过射线检测当前物体的在World中的Hit情况,继续看下ComponentSweepMulti
1 | FInlinePxShapeArray PShapes; |
这里是进入物理引擎检测之前的准备,检查当前物体上有几个物理Shapes。调试发现,正常碰撞和非正常碰撞的差异在这里的NumShapes就不一样。继续FillInlinePxShapeArray_AssumesLocked
1 | int32 FillInlinePxShapeArray_AssumesLocked(FInlinePxShapeArray& Array, const physx::PxRigidActor& RigidActor) |
这里就正式进入物理引擎进行shapes的检测了。 既然这里产生差异,那问题就出现在碰撞物的mesh文件上了。仔细对照该文件和其他正常能碰撞的FBX的文件发现, 原来Convex Collision的数组信息为空 !!!
到这里,遇到的这个诡异的问题也算初步解决了。回头看其实是一个很基本的问题,主要根源还是对UE引擎的不熟悉。这里汇总下来做一个反思,希望后续继续努力深入学习UE引擎。另也备忘下,给遇到同样问题的朋友提供点思路。