Particle Location Module Mini Tutorial
Warning: Check sim targets, attribute readers can currently not read between cpu and gpu so your source and target sim targets need to be the same!
The intention of these mini tutorials is to have easily searchable reference for implementations of some of the newer (or altered) features in Niagara.
Using the particle attribute reader data interface we can make a reasonably optimized particle location module.
The goal is to find, on execution, a valid particle in the chosen emitter to take the location over from.
There is two ways to follow the tutorial, either you make it yourself using the descriptions and images, or you copy over the contents of this pastebin to a new module script, and then just use my steps as explantions of the inner workings
Here is a pastebin to the raw code of the module, you can past this inside of your module editor and it will convert it to nodes.
don’t forget to plug into the Output node after copying.
- Make a new Niagara Module Script
- Open the module, we are doing to start by setting up our particle attribute reader
- Add a Particle Attribute Reader Parameter to the Map Get Node, and call it something like PAR
- Pull a Get Num Particles to find the amount of active particles in the Map you are reading from.
- Also create a Random Range integer and with an input between 0 and Num Particles-1
- Call Get Vector By Index with the following inputs
- Attribute = Position (This return Particles.Position of the chosen emitter)
- Particle Reader = our particle attribute reader parameter
- Particle index = the random integer we generated
Blue nodes like this can be converted to static inputs, in this case we are working with integers, so choose int32
Get Vector by Index will return two outputs.
- A bool expressing wether the value you just tried to pull is available
- The value of the Map at the index position for the given attribute.
- Add another Map Get node (we could do it with the original one, but it will get a little bit messy)
- Add an if node for the validity check inputing vec3(0,0,0) in case of false (this is technically not nececary as the default value for the pull is also vec3(0,0,0), but this is safer and easier to read)
- Subtract Engine.Owner.Position from this value to find the local position of the particle. We need local positions because we plan to add this into the current particle position instead of overwriting earlier location modules.
- From the subtract node, add this value into Particles.Position, then in Map Set, assign it to Particles.Position. (This is usefull if you already used a sphere position node to create offsets, these offsets will be preserved)
- Also drag out the Valid output from Get Vector by Index and feed it into DATA.INSTANCE. Alive, this will kill particles if there is no particles to spawn from. (There is a little performance hit for spawning the particles in the first place, but it still better then simulating those particles every frame for no reason)
And thats pretty much it if you just want to spawn particles at another particles’ position.
I do suggest adding a velocity enheritance to this module as well, as that is very useful for a plethora of effects.
- Add another Map Get and add a new float input inheritVelocity
- We can also add our Particle Attribute Reader input from earlier by clicking and dragging it from the parameter window.
- Call Get Vector by Index on our particle attribute reader parameter with the following inputs :
- Attribute = Velocity
- Particle Reader = Out particle attribute reader parametere
- Particle Index = The same index as calculated in Step 2
- Multiply the return value with our inheritVelocity parameter, this will give us control over what fraction of the source velocity will be inherited.
- Then add it to Particles.Velocity and set Particles.Velocity. Same as for the position, we want this so this module doesn’t overwrite our values calculated in previous velocity modules.
It is useful to expose this module to the library under Location (that’s where it was in cascade at least :D)
The highlights will help you identify the type of module in the emitter stack.
And the description is useful for your teammates, or yourself in a few months
Please let me know if you don’t understand something, or if I made a mistake somewhere.