Playing a Niagara System in Reverse

Hey all again,

Been awhile and thanks again for all the help in past times.

So I wanted to ask everyone their thoughts on reversing a Niagara system, as in playing a Niagara system in realtime backwards.

From initial experiments I thought as it could play backwards in the sequencer, that I would be able to do the same in real time. However after investigation, it seems like technically when you are playing a Niagara system backwards its actually doing another sim, so in my situation that is not what I’m looking for.

After looking further into it, I have read about driving a Niagara systems not by time but by a value that I pass in.

The end goal is to be able to play a Niagara system by a parameter (set between 0-1) so that at 1 its the end of the systems life cycle and 0 is the start, so it can be played back and forth.

I wondered if this was a valid way of going? Anyone had experience in this or have a better recommendation?

All input is always appreciated, cheers all!

It sounds like something in Life Is Strange 1, isn’t it? I don’t have any actual experience in such effect, but I think UE 5.1’s new feature for Niagara “Simulation Cache” would interest you, but it’s an early experimental feature. There is no official documentation about it whatsoever, I don’t see any relevant resource in Epic’s Content Examples either, but I could be wrong. Even if you could get Sim Cache to work now, there is no guarantee it would work in the next UE update.

A rather primitive approach as you’ve already suggested is to use a float user parameter to act as a lerp alpha/curve index/time base to slide between the initial and destination positions of all particles. You can’t rewind velocity/force driven motion (not without Sim Cache anyway), so all particle movements have to be faked by direct manipulation of the binding position attribute.

I set the System attribute “CustomTime” in System Update stage so I don’t need to use a BP to control the user parameter or slide the time value manually. Again you’d expose the float value via user parameter and fetch the time value from blueprint.

2 Likes

Hey @ifurkend,

Thanks alot for this. Really helped get me started.

I was able to drive a system using a user time and still using the same nodes plugged into them. So I was able to switch around the modules to get something that is working well (mostly by adding particle update nodes into particle spawn section).

My question now is I cant seem to get spawn rate to work with a user time. I cant add the spawn rate to the emitter spawn section like I did with other modules (or at least it didn’t work for me). I also tried configuring this section of the module to get it to work (by replacing delta time with my custom time with no luck):

I wondered if you have any insight into getting spawn rate working with a custom usertime variable?

You mentioned sim caches. I can record a sim cache, but how do you play a sim cache back? Do you use the same system?

Again thanks for any input!

Short answer: I don’t know.

Long answer: There doesn’t seem to be any official resources or example project of Niagara Simulation Cache so it’s all but a black box. I am not an Epic TA or familiar with any, so I just don’t have the time and resource to decipher something like that.

As for making spawn rate to work with user time, I don’t think so. You cannot kill a particle and revive it again (Although I have heard that it is possible under a very unusual circumstance, I’d rather not attempt it). First let me get it straight, my user time rewind method doesn’t work with velocity. I have to state that again because in your screen shot you still have all the velocity/forces modules in your “reverse demo” emitter.

My method also requires all the particles not to be killed until the Niagara System instance is destroyed externally.

What you can actually do is to fake spawn rate by delaying all burst particles by particle’s uniqueID: max(User.UserTime - Particles.UniqueID * ConstantRate, 0).

1 Like

Thanks for reply @ifurkend.

I was trying to implement the spawn myself but it seems to error when trying to access Particles.UniqueID.

Any ideas what im missing?

I don’t mean to control the spawn count, but to create a new float parameter in Particle Update stage “CustomTimeDelay” and replace the System.CustomTime in the particle position curve index.

Hi, I’m very interested in replicating this behavior. I want to be able to make particles return to the initial position after moving with a curl noise or linear force. My initial idea from Unity was to work with some set position nodes in the update section, but I found your workflow more practical. I’m new in Niagara and understand this workflow, but I cannot recreate the nodes from this video. Could you provide a more broken-down video version or links to learn how to make this? Thank you!

Not sure which part you’re unable to reproduce.

If you are working with UE 5.4’s Sequencer, you can use its formal release of Niagara Simulation Cache. The baked cache can be set to play reverse in the cache properties and different play rate. I did some digging in BP, but all it allows is to simply bake the SimCache, no function which would allow to replay the SimCache.

This official SimCache Sequencer tutorial focuses on Niagara Fluid, but it works exactly the same for non-fluid Niagara System:

Hey,

Sorry for the late reply, but we eventually found a pretty solid solution with what Thomash mentioned which was using simcaches to record the effect in realtime. We needed to do that because some effects we couldn’t get away with it just playing a similar cache over and over e.g. missile trails could go in any direction.

So we made a blueprint which recorded it in realtime and then played that cache once we recorded it to a certain point, we had the extra layer of complexity which was the player could reverse time to any length so again thats why we needed to record in realtime.

I will reach out to the coder who implemented it, so he can shed some more light on that side as there were afew issues with using it such as it couldn’t cache GPU particles currently. The issues should all be fixed in the near future though.

So talking to the coder he came back to me:

We managed to get SimCaches working pretty well for rewinding

The simcaches all take up memory, and if you have lots of dynamic VFX going on at the same time this memory might quickly add up, it’s just something you need to be aware of.
Also it depends how long you need them to stay in memory for.

For our game, we had a rewind buffer of around 30 seconds, so we had to keep 30 seconds worth of every rewindable simcache at any one time - this could quickly get big.
The other main issue is that the SimCache recording is not yet optimised for effects on the GPU - recording GPU effects to SimCache will be a major performance drain until that has been dealt with.
At the moment it’s basically trying to pull data back from the GPU when it’s not really meant to, making it very costly (layman’s explanation).

It would be hard to give you an out of the box solution to this, as our solution was a mix of C++ and Blueprint.

I’ll try to give a brief overview but it will require some trial and error.
As far as I’m aware there’s no reason why all of this can’t be done in Blueprint, so bear that in mind if you are just experimenting.
This is the jist of what we did:
When the effect is started set it to record to simcache

When you want to rewind the effect cancel the async action and set the simcache on the effect (so that the effect is used)

When you have finished rewinding, clear the sim cache and go back to the first step (set it to record again)
SimCacheClear

All the while, in the tick function (we had ours in C++, but again no reason why you can’t do it in BP), call this:
_NiagaraComponent->SetAgeUpdateMode(ENiagaraAgeUpdateMode::DesiredAge);
_NiagaraComponent->SetDesiredAge(TimeAlive);
Where TimeAlive is the rewind-dependent time value that is driving the effect.

Hope that helps in your work!

1 Like