Any infos about the Niagara pooling system?

Hello,

if you spawn a Niagara system, it has pooling method options like “Auto Release”, “None” and “Manual Release”. I did not find any information about how this pooling system works. Where can I set the size of the pool? Where can I decide when to fill the pool? What if the pool is not big enough to take an item from it?

Thank you,

Thilo

5 Likes

4 years later, still no info on this :sweat_smile:

Pooling only benefits you when you spawn a lot of the same FX in a short amount of time. For example bullet impacts in a shooter game. It often causes more confusion than it does good, so I would recommend to use data channels instead.

“Auto Release” - this is the pooling option you want most of the time. Set “auto destroy” to true for the system you spawn and don’t hold a reference to it or touch it after it has finished.

“Manual Release” - It won’t go back into the pool, so you can keep a reference to it and retrigger it. Once you’re done with it you need to release it back to the pool, otherwise you’re leaking the component.

The pool can never run out of components, so don’t worry about that. There is not a lot to configure, but you can look at the cvars that start with “FX.NiagaraComponentPool.”.

3 Likes

I’m also trying to make use of the pooling method for projectiles flying with a speed (not instant).
I first tried implementing my own pooling method, by creating a sufficient number of niagara components and then just activate/deactivate them and afterwards pass position vectors to the NiagaraComponent to update the particles positions.

but there seems to be a delay and the particles don’t seem to travel as smoothly as when I would use
UNiagaraFunctionLibrary::SpawnSystemAtLocation, and then just move the whole NiagaraComponent instead.
I checked the memory addresses of the NiagaraComponents, and even after spawning the same FX around 50 times in a time frame of a couple of seconds, it was always a unique memory address and also the componentids were always unique (NiagaraComponent_0 to NiagaraComponent 49).

I used ManualRelease when spawned, and then deactivated and ReleasedToPool when the projectile has hit something or lifetime exceeded.

edit:
i checked the default cvars for the pooling.

FX.NiagaraComponentPool.CleanTime
FX.NiagaraComponentPool.Enable
FX.NiagaraComponentPool.KeepComponentsRegistered
FX.NiagaraComponentPool.KillUnusedTime
FX.NiagaraComponentPool.Validation

it seems to be enabled by default and they seem to be reasonable, unless the default value for
FX.NiagaraComponentPool.KillUnusedTime = 180, is in milliseconds.

edit:
I tried a FX.NiagaraComponentPool.KillUnusedTime with a reasonable value, assuming it’s in milliseconds (10000).
I spawned around 50 NiagaraComponents, after each other while being deactivated and released to pool inbetween.
the memory addresses of the NiagaraComponents were still all unique.

So I’m not sure if the pooling method is enabled by default or if it doesn’t pool them at all.

edit:
I did a mistake by actually not calling ReleaseToPool(), eventhough I thought otherwise.
I did another check and the pooling method works properly. I spawned around 50 FX, and they are getting reused. One memory address I checked got reused 4 times.

I also did some deep diving into the NiagaraComponent Pooling, and if I understood correctly it get’s the max pool size from the NiagaraSystem asset used for the NiagaraComponent. It’s probably the value you can set inside the Niagara Editor for NiagaraSystems, inside System->Performance->MaxPoolSize

//Don't add back to the pool if we're no longer pooling or we've hit our max resident pool size. Also if the component's world is in the process of tearing down.
if (GbEnableNiagaraSystemPooling != 0 && FreeElements.Num() < (int32)Component->GetAsset()->MaxPoolSize && Component->GetWorld()->bIsTearingDown == false)