Basic Niagara Structure Mini Tutorial
As you get more comfortable with building content in Niagara you might want to familiarize yourself with the underlying structure of the tool. This can help you avoid common pitfalls or solve issues.
This post is rather big, so I recommend skimming through first.
So what even are particles?
Niagara Particle
In Niagara particles are essentially just a list of “stuff”, typically position, velocity, but just as often also color and acceleration. The “stuff” here can be completely arbitrary in theory, but Niagara has been setup with some default stuff.
We call the “stuff” here parameters or attributes.
These parameters are have different values across particles, but their structure is shared. So if you have position in one particle in an emitter than all particles must have a position.
Niagara Emitter
An emitter is a collection of these particles, essentially a singular one of these lists. The Niagara Emitter is also responsible for managing the creation and removal of the particles as well as managing it’s own lifetime.
Niagara System
If an emitter is a collection of particles, a system is a collection of Emitters. The idea is that instead of the game managing all emitters separately, we group them into “an effect”. This effect can then be created in it’s entirety simply by asking the system to spawn it’s emitters.
Niagara Component
Components in Unreal are outside the scope of this tutorial, but suffice it to say this is a container class to hold common functionality. The Niagara component holds a system and essentially manages the existence of this system as well as it’s transforms, bounds etc.
Besides the component you can see this separation in the Niagara UI. Blue acts on the system, orange acts on the emitter and green acts on individual particles. These sections are also called stacks, for example the Particle Update Stack in the following image only has a Particle State module in it.
So what are these modules I keep hearing about?
Modules are essentially little scripts that tell the emitter, system or particles to do something. For example you might have a module that tells particles to set it’s location to -500 in the z axis. Some common modules you might want to be aware of :
- System State decides whether or not the system should be active and keeps track of some common system variables like Age and other timekeeping things
- Spawn Burst Instantaneous and Spawn Rate manage the creation of particles in the emitter.
- Particle State calculates Age and other timing related variables and checks if the particle should still be alive, marking particles that shouldn’t be.
- Solve Forces and Velocities manages physics related properties of particles and applies any change that is necessary to the intrinsic attributes (like position, velocity, acceleration etc…)
There are rather a significant amount of modules already build by epic and you can extend / build your own modules.
What about this Spawn and Update thing?
These are indications of when these scripts should run, modules placed in a spawn section will only run when the system/emitter/particle is created, the updates will be only run when an update is requested to the system/emitter/particle.
In fact, it will run these scripts in the order they are placed in these sections. (higher modules will run first)
This can be important to make sure certain information is available to work with. For example if one had added velocity after applying this velocity to the position, the particle would always lag a frame behind.
Pro tip : Try and keep the general order of your modules the same throughout all effects. Physics => Post Physics => Color => Scale, or whatever you prefer. This will help you quickly identify what an emitter is supposed to do and find issues.
Spawn and Update are the most common stages, but it is possible to add arbitrary stages to the particle stage list. This too is out of scope for a small tutorial. You can think of stages as collections of scripts to be ran at some point.
Namespaces
Namespaces are these tags next to parameters, they range from straightforward namespaces like System, Emitter and Particle to downright confusing like Transient??
Let’s start with the easy ones :
- System and Emitter are for parameters that need to be written to by system and emitter scripts respectively, they cannot be written to by any other structure, but can be read.
- Particles is for each of the parameters in a particle. Particle can write only to their own parameters (so not to any other particle’s particle parameters) and Particle Parameters can only be read by that particle (by default)
- Local parameters are only writable and readable in the current script, they get thrown aware after that script is done executing.
- Input parameters are only readable in the script and never settable, they indicate that a parameter should be exposed by the module UI
- Output parameters are only writable in a script, but will remain available for reading after the script is done executing, they will be thrown away once the current stage ends (end of update or end of spawn etc)
Stack Context
The stack context is a shorthand to write System, Emitter or Particles depending on where the parameter is being used. If the parameter is being used in a script in the System stack, then it will be placed in the System namespace etc.
Transient
A transient parameter is, similarly to output, only available for the current stage, but can be written to and read from by any module in that stage. It’ll get thrown away once the current stage is done. Think of it as something between a particle and output parameter.
Aren't there a few missing?
Yup, we didn’t talk about Engine Provide, User Exposed and Niagara Parameter Collection yet. All of these parameters are read only within the system, the are mainly used for piping information from all over the game into Niagara
User Exposed
These are arbitrary parameters settable by bp, c++ etc per component. Extremely useful for driving particle behaviour based on gameplay and still to this day underappreciated by most VFX artists. One big caveat about user parameters is that they are not readable inside of scripts and instead need to be piped through input parameters
Engine Provided
A limited number of inputs that give information about the game are always available, things like the owner (component) transform and the deltatime this tick.
Niagara Parameter Collection
Is similar to Material Parameter Collections, it allows you to keep an instance of parameters shared across the game (so anything anywhere can write into it) and then provide that instance to any Niagara system that needs it. This too is unfortunately not available within modules.
What's Data Instance?
From the point of a VFX artist this might as well just be a Particle Parameter. There’s only one and it indicates whether or not the particle should be alive.
If this one is false by the end of the particle update stack your particle is gone, so do be careful
Hopefully this gives a good initial idea of how Niagara is structured. Let me know in the thread below if you have any questions or corrections you would like to make.