[UE; Niagara] Animating particles after System Deactivation

Not sure if this is a niche use case, I found myself using it more and more and just thought I’d share!
TL;DR
A niagara module that lets you animate particles after the system has been deactivated.
Tutorial/node graph at the bottom.

Scenario #1: You have an infinite particle that is supposed to fade in and out based on whether the System is Active or not

Scenario #1 Infinite particle

In this example, the colors are just to help visualize the ‘states’
Green - system activated, fading in
Blue - done fading in and is now living infinitely (until system deactivation)
Red - system deactivated, fading out
InfiniteParticleExample

The setup:

Scenario #2: You have a System continuously spawning particles with very long lifetimes, however, in case the System Deactivates, you’d prefer to quickly fade out all the particles.

Scenario #2 Continuous Emission

In this example, the colors are again just here to help visualize things
Green - the particles are living their lifetime as they normally do
Red - system deactivated, fading out no matter the lifetime
ContinuousSpawnExample

The setup:

I found that for me, in both of these scenarios, having a separate curve to scale/erode/fade particles in the Niagara System itself is the most convenient, rather than relying on outside parameters or spawning an entirely new system with its only purpose being to fade out. This has led me to create this Niagara Module.

How it works

The module works in conjunction with the default ParticleState module.

There is a single parameter in the module called InactiveLifetime.
By default it is not used and instead, the module stops Particle Age attributes from ticking until the System/Emitter is Deactivated. This means that anything you animate by NormalizedAge will run after Deactivation.

If you do use InactiveLifetime, the module won’t modify Particle Age attributes.
However, it creates two extra Particle attributes ‘InactiveAge’ and ‘NormalizedInactiveAge’.
These two parameters work the same way as their non-inactive variants, the difference is, again, they are ticked after System/Emitter deactivation.

NodeGraph / Module link

BlueprintUE link (5.1)




Feel free to modify or use it in whatever you like.
Also to comment something absolutely trivial that achieves the same thing without the added ‘complexity’.
One might also argue, that a module just straight up counting time could achieve the same things. (oh well)

In any case, some known issues as well:
The module has to be directly after ParticleState, if theres anything inbetween the two, NormalizedAge might tick up for a frame(?) (happened to me on UE4.26, haven’t tested on later versions).

Update 1.1

BlueprintUE link (5.1)

Added the option to DISABLE killing the particle when InactiveLifetime elapsed (Advanced option, defaults to kill)

This can be useful for even more niche cases, where you do want to animate some Particle Attributes after the System Deactivates, but you’d also like to keep it’s full Lifetime.

18 Likes

Hi Guraoz,
Just wanted to say : thanks for sharing this ! Never thought about looking for such feature, but now that I read your post I think it is a very good idea indeed. I’ll give it a try !

You’re welcome! Hope the explanation made sense!
If you happen to run into issues don’t hesitate to let me know!

Hi Guraoz, :slight_smile:
Just wanted to share with you some issues / improvement I found while working with your Particle Decay setup.

  1. Issues with emitter’s scalability system :

I was using the particle decay setup for a infinite particle I sometime want to deactive from a blueprint. I’m also using visibility culling for this particle inside the emitter scalability. With both visibility culling and particle decay together, if you look away from your system, the emitter will go to sleep du to the scalability, then the particle decay script will see that as some kind of deactivation and will run as intended, the particle will be killed (if enabled), and when you look to your system again the sprite won’t show up anymore.
To handle this issue, I added another condition for the script to run :slight_smile:


So now the script will not only look to current emitter & particle execution state, but will also look for the emitter execution state source. If the emitter was deactivated by the scalability of the emitter, it won’t run the particle decay script anymore, but if I deactivate the system by blueprint the source will be “owner” and then the script will run as intended.

  1. Custom decay triggering condition :

I also thought it could be usefull to be able to select a custom condition for the script to be triggered. I added a “Custom Condition” bool input parameter to be able to choose whatever reason you could think of to trigger some particle decay.


One obvious usage would be to be able to fade out particles instead of instantly killing them in some cases.
Let’s say you have some particle that you want to kill if they get too far away from the player. The obvious workflow would be to use a “Kill Particle” module, and fill the condition of the kill particle with a distance check between particle position and player position. It does work, but your particles will die instantly when it happens.
Instead of killing your particle, you could use the result of the distance check as a condition to trigger the particle decay and have a proper fading out animation.

Hope those feedback will be helpfull, and thanks again for the idea man, I’m using this on weekly basis now that I have it :slight_smile: :pray:

1 Like

Definitely an important fix and a useful idea!

I’ll update the BlueprintUE version once I have the time and link to your above post in the changes!
I’m happy you found it useful and that you found improvements!

Hey Guaraoz, this is exactly what I’ve been looking. Im doing an effect where I have an infinite particle that I want to fade out after the system is told to be deactivated. However, I’m not the sharpest tool in the box when it comes to Niagara, still learning, and I’m coming across a problem.

I tried to take the BlueprintUE code and just copy/pasted it into a new scratch module, but as soon as I “apply scratch” it to my effect Unreal just crashes.
I then tried to make a new script module instead, and pasted the code into there, but when I compile the module it reports errors of ‘defaults found for variable [xxx], not but not found in ParameterMap’.

As I’m only starting out and scratch pads and modules are very much new to me can you, or anyone else, point out where I’m going wrong? I was hoping for a module I could just hook into my effect and use to make it fade out nicely on deactivation, but I’m clearly doing something wrong. Included an image of the errors I get when trying to compile the module.

Hey!
Sorry about the super late response, I’ve been busy with life!

I can easily reproduce the crash (which happens if you paste it into a scratchPad module and try to compile) and your errors (which show up, when you create a separate module), and I’m not sure what changed (most probably the website updated).

The issue is (at least on my end) that all the parameters are incorrect data types…
for example Particles.ParticleExecutionState turned into Position, instead of ENiagaraExecutionState
sadness

I’ve diffed the version in my project to the one hosted on the BlueprintUE website, and… they do not produce the same code.

All that being said, I’ve updated the BlueprintUE version, which broke the website visuals, but seems to work in an empty project (5.1) when pasted into a module asset (I’ve not tried pasting into scratchPad).
So please give it a shot and feel free to report back if you still have any issues!
I am more or less around for the time being.

No problem, we are all busy.
I have quickly grabbed it and it does seem to compile inside 5.3 happily now, so safe to assume its working as expected again. Thanks for taking a look and updating the BlueprintUE version.

1 Like

You’re saint, man!

Thanks a lot for sharing! Have been looking for such feature for a while.

Will try to recreate it now

1 Like

Finally, I encounter the case you mention. I’ve crossed this post before, and now, I’m here to pay my respect :pray:

Haha yeah, I think it’s one of those things that isn’t immediately obvious when you’d need it.
I swear I use it so often I can’t even count now. (actually I can, by account of the ref viewer its over 600 systems, holy cow)

Hey, I was wondering if you might have any idea why in 5.5 this would be crashing again when you try and copy and paste it into the scratch pad?

Are you using 5.5 Preview?
I can reproduce the crash upon compilation, not directly from pasting.
Seems to be the same problem as before, where things turn into null, or just random data types; not sure if there’s a way to future proof copy pasting from older versions.

Anyways, a relatively quick fix is having a 5.1 project, creating a module there, and migrating that to your 5.5 project.
The other method would be to fix up all the data types and reconnect everything which is quite tedious…

For your convenience, I did the migration fix, and put up a UE5.5 version to BlueprintUE which can be copy pasted into a fresh 5.5 project.

I will not be doing this for every single version however, so if anyone runs into the ‘crash on compile’ issue, please try migrating it yourself first!

1 Like