The intention of these mini tutorials is to have easily searchable reference for the implementation of basic ideas in Niagara.
Today I want to have a quick look at how we might solve a common issue when using Ribbons.
Unless you spawn a particle every single frame, there will always be a gap between the source of the ribbon and the ribbon itself.
Spawning a particle every frame, can be a solution in some cases, but it’s often better to find a solution in which you can bridge that gap
There are a few strategies to deal with this, but I’d like to present a fairly basic one that will work in a large number of situations.
The strategy here will be to reliably find the last spawned particle and snap it to our source location (the emitter position in this example).
We do this by, for every particle, comparing the index of that particle with the total number of particles that have been spawned in the emitter. In the case that we do have the last spawned particle, we set the Position of the particle to the simulation position.
Now to know the total number of particles we still need to keep track of that somehow.
To do this, we’ll adjust the SpawnPerUnit and SpawnRate modules. (You’ll probably want to create a copy for this.)
At the end of the modules we can add a little section that reads the spawn count and adds it to Emitter.TotalParticlesSpawned.
And boom now the last particle of your ribbon will remain attached to the source.
Except that’s not entirely the case.
Due to tick order it’s possible that this script will be executed before the movement script of the source.
This can create a one frame gap between the last particle and the source.
We can solve this on a case by case basis, by forcing the Niagara Tick to later in the frame.
This is generally ill advised because it takes away the engines ability to make use of threading in an efficient way, but if used sparingly it can be helpful.
After GPU Ribbon is available to Niagara I’m no longer too bothered with this issue, but I still want to share a less accurate but slightly easier solution to the gap issue when using Spawn Rate.
This approach assumes the user to stick with a constant spawn rate value, because there is very little point of randomizing the spawn rate value every frame in a ribbon emitter. Anyway because the spawn rate value is constant, we can simply calculate the spawn interval in second by 1/SpawnRateValue, then in Particle Update stage, do a Lerp Position and choose between SimulationPosition and Particles.Initial.Position (or just Particles.Position depends on your use case) by checking if the Particles.Age is smaller than the spawn interval.
If we are talking about the same guy, he actually wanted the newest particle to go beyond the actor position, which is possible with our methods, but it saddens me that it no longer matters now (not because of the GPU ribbon).
I have a question, because I am unable to read what is before this (or more like they’re too advanced!), what does SpawnOutputInfo return? To my understanding, it seems you’re taking out the every count of particle spawn and accumulate them to the Emitter.TotalParticlesSpawned.
It would be great if you could explain more about this part, thank you.
it seems you’re taking out the every count of particle spawn and accumulate them to the Emitter.TotalParticlesSpawned.
Yup, that’s exactly what we are doing.
Spawn info is the structure a spawn module passes onto the engine to indicate that it wants to spawn new particles.
If you open up one of the epic provided spawn modules, you’ll notice that the last node in those modules is the one I marked in white.
So we simply copy the epic provide modules and put those nodes in the picture behind it to check how many particles this modules wants to spawn and add it to our count.
I’m not sure what to do since two of them are located on nodes that came from the basic spawn rate module. The last one is the map set at the end (the one you add) but I suppose this error is caused by the two others errors.
Oooooh I didn’t look there, I feel a bit silly now… I also had an interrogation : I have a missile effect using a ribbon as a trail with the event handler but there is a big gap, does the method you show is the same to fix it or is there some changes ?