Hi,我们在项目中遇到一个Niagara生命周期相关的问题
<br/>
我们通过ReleaseToPool()或者Deactivate()关闭Niagara系统后,Inactive Response设置为Complete的粒子系统会进入等待粒子结束状态。如果在粒子系统等待的过程中切换了ViewTarget(这会触发Niagara Scalability的全量刷新FNiagaraWorldManager::RefreshOwnerAllowsScalability() ),粒子系统就可能会在刷新Scalability之后被Scalability的恢复逻辑重新激活,导致预期应该关闭的特效没有关闭
<br/>
我们预期中,ReleaseToPool()被调用后,组件应该进入Release流程,不应该因为Scalability的恢复逻辑重新进入Active状态。
我们想要确认,上述表现是UE的预期设计吗?我们是否存在用法/配置方面的问题,有官方推荐的修复方式吗?
<br/>
谢谢
<br/>
[Attachment Removed]
重现步骤
引擎版本:启动器版本的UE 5.7
复现需要:
1. 一个具备任意剔除手段的Niagara Effect Type(最大距离、视锥体、Without Render均可),Effect Type的Cull Reaction需要设置为Asleep或者Asleep and Clear
2. 一个使用上述Effect Type,并且Inactive Response为Complete的粒子系统
复现步骤:
1.Spawn一个粒子系统,播放一段时间后使系统Inactive(正常走完生命周期、ReleaseToPool、Deactivate均可),此时粒子系统停止发射,进入等待Complete的状态
2.在系统等待Complete的这段时间里切换ViewTarget(目的是触发RefreshScalability),并触发Effect Type的Culling Method
3.切换回原来的ViewTarget,当特效再次通过Cull测试的时候,系统会被重新激活
可以进入附件项目的TestMap地图,运行游戏后,在Outliner中找到BP_CameraSwitch,调用它的ReleaseAndSwitch事件即可复现问题
[Attachment Removed]
RoryXY
(Xiao Yue)
4
您好,
工程里的Niagara Effect Type中设置了Visibility Culling(Max Time Outside View Frustum), 且Cull Reaction为Asleep, 那么只要这个system instance仍由scalability manager管理, 就仍然可以因为回到相机视窗被再次唤醒激活. 如果希望ReleaseToPool后不再被激活, 要么可以把Cull Reaction改为Kill或Kill and Clear, 要么设置niagara component的Allow Scalability为false.
[Attachment Removed]
好的,感谢回答,觉得在管理特效生命周期的时候加上Allow Scalability的处理会好一些。但感觉当前实现下Cull Reaction的语义有些过于泛了,特效即使被主动ReleaseToPool/Deactivate也会被作为Asleep状态在Scalability Manager中进行管理,这样看来似乎没有一个能够确保稳定关闭Asleep类型特效的原生接口?
[Attachment Removed]
RoryXY
(Xiao Yue)
6
这个地方确实有点反直觉, 调用Deactivate时仍然会根据system是否complete来设置Active状态, 参考UNiagaraComponent::DeactivateInternal中的这一行
SetActiveFlag(SystemInstanceController ? !SystemInstanceController->IsComplete() : false);
而你的system state里的Inactive response设置又是需要等待粒子全部死亡才会complete, 所以切换视角仍然会被scalability manager接管. 如果需要一个忽略asleep, 忽略是否complete来关闭特效的接口, 调用UNiagaraComponent::DeactivateImmediate应该是可以的.
[Attachment Removed]