ue4.26 niagara collisionNormal问题
目的是让粒子片自由下落,与表面碰撞后停止并调整为与表面一致的朝向。
测试用例搭建如下:
1,建一个niageraSystem,直接用Fountain模板。
2,确认Emitter Properties中Sim Target是CPUSim(出于兼容性考虑)
2,在Solve Forces and Velocity前添加Collsion模块(CPU碰撞)。
3,将Collision中的Friction和Friction During a Bounce都给很大的值,不希望落地后滑动或反弹。
4,Emitter Settings中Interpolated Spawning去掉勾选。(无关紧要)
5,Emitter State中Loop Behavior改成Once。
6,关闭Spawn Rate模块,添加Spawn Burst Instantaneous模块,Spawn Count设置为100,Spawn Time设置为0。
7,Initialize Particle模块中Lifetime设为-1,适当调大Uniform Sprite Size。
8,关闭Sphere Locationty和Add Velocity in Cone,添加Box Location,给适当的box size。
9,关闭Drag和Scale Color。
10,将Render中的Facing Mode改为Custom Facing Vector,鼠标放在上面会有提示:此模式下是通过设置Particles.SpriteFacing调整粒子朝向。
11,在Parameters下的Particle Attributes下添加SpriteFacing变量,然后在Particle Spawn阶段赋值(0,0,1),在Particle Update末尾将[Transient]CollisionNormal赋给SpriteFacing。
注:niagara parameters中显示transient变量,需要勾选show advanced categories
将粒子放在斜面上方播放,在原版ue4.26下表现符合预期,粒子落地后就面向地面法线方向。
但在项目引擎里却效果却不对,粒子落地后还还是朝上。
说明在项目引擎里CollisionNormal不正确,于是怀疑是项目引擎修改过产生了bug。
用引擎源码启项目调试。
搜CollisionNormal,可以找到其赋值处:
可见,是由CollisonTraces中取得Hit信息,然后将Hit.ImpactNormal赋予CollisionResults中的元素的CollisionNormal。
跳转到CollisionResults的定义:
然后find references,可以找到从CollisionResults里取结果的函数:
GetQueryResult的调用处为:
这也正是CollisionNormal赋给transient变量CollisionNormal的地方了。
为了调试方便,将Spawn Burst Instantaneous中的Spawn Count改为1,即只生成一个粒子。待粒子落到斜面上后如下打断点:
则会发现第一个断点有时能断到,有时断不到,断点1断到的时候继续运行到第二个断点时CollisionResults中元素个数就是1,而且CollisionNormal值确实为斜面法线,断点1断不到的时候直接运行到第二个断点时CollisionResults中元素个数就是0(Empty)。
也就是说,当CollisonResults非空时法线是正确的,只不过有很多时候是空。
而出现为空的情况也不能断定就是有错,因为有可能那帧确实没监测到碰撞,就是[transient]CollisionValid=false的情况(尽管粒子都已经落地了还有监测不到碰撞的情况也让人觉得不太正常,而且原版引擎就不会这样)。
如果不深纠和原版引擎一样,而只是想个办法把问题绕过去的话,那么现在已经有方法了。方法是:既然CollisionNormal时有时无,那就自定义一个CollisionNormalLatest,用它来记录最近的一次有效的CollisionNormal,用这个Normal作为最终粒子朝向。
于是emitter修改如下:
1,添加InitCollisionNormalLatest模块,将CollisionNormalLatest初始化为(0,0,1)
2,添加SetFacingUseCollisionNormalLatest模块,计算CollisionNormalLatest并赋给SpriteFacing:
3,添加ClearVelocityAndForce模块,将已发生碰撞的粒子Velocity和PhysicsForce清零,另外对于已碰撞的粒子还要关闭Collision和Gravity Force:
这样,粒子落地后,朝向就正确了: