ue-niagara-effects
Use this skill when working with Niagara particle systems, VFX, effects, emitter, Niagara component, or Niagara parameter in Unreal Engine C++. Covers spawning systems, setting parameters, data interfaces (SkeletalMesh, StaticMesh, Curve, Array), OnSystemFinished delegate, and performance tuning. Se
By quodsoler · 888 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-niagara-effects
Source repository · Upstream listing
UE Niagara Effects
Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
Niagara ships as the Niagara plugin ( Engine/Plugins/FX/Niagara , enabled by default). Game code spawns and drives systems through UNiagaraFunctionLibrary and UNiagaraComponent , feeds them structured data through data interfaces and Niagara Data Channels, and controls cost through component pooling and UNiagaraEffectType scalability. Add "Niagara" to your module's PublicDependencyModuleNames , plus "NiagaraCore" when you subclass UNiagaraDataInterface .
Context
Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
Request is about… Go to
Asset, emitter and component relationships [System and Component Model]( system and component model)
Firing an effect, attaching a trail [Spawning Systems]( spawning systems)
Activate, reset, pause, seek [Lifecycle Control]( lifecycle control)
Pushing floats, colors, vectors into an effect [Setting User Parameters]( setting user parameters)
Skeletal/static mesh, curve, array, texture DIs [Data Interfaces]( data interfaces)
Exposing game specific data to Niagara scripts [Custom Data Interfaces]( custom data interfaces)
Gameplay events into Niagara, VFX to VFX messaging [Niagara Data Channels]( niagara data channels)
Knowing when an effect is done [Completion Callbacks]( completion callbacks)
Recording and replaying a simulation [Simulation Caches]( simulation caches)
Cheap high count emitters [Lightweight Emitters]( lightweight emitters)
Spawn cost, reuse, priming [Component Pooling]( component pooling)
Culling, tick order, determinism [Scalability and Tick Behavior]( scalability and tick behavior)
Build.cs and includes [Build Setup]( build setup)
System and Component Model
Authors expose parameters to C++ by placing them in the User. namespace in the Niagara editor. Only User. parameters can be overridden at runtime; System. , Emitter. , Particle. and Module. are simulation internal.
Discover what an asset exposes without opening the editor:
Spawning Systems
Attached, persistent effect. Note the argument order: bAutoDestroy comes before bAutoActivate here.
A second SpawnSystemAttached overload inserts FVector Scale after Rotation and then orders the tail as LocationType, bAutoDestroy, PoolingMethod, bAutoActivate, bPreCullCheck . Pick one overload deliberately; the two are easy to confuse.
SpawnSystemAtLocationWithParams and SpawnSystemAttachedWithParams take a single FFXSystemSpawnParameters struct ( Particles/ParticleSystemComponent.h ) when you want named fields instead of a long argument list. That struct carries EPSCPoolMethod PoolingMethod , not ENCPoolMethod .
For an effect that repeats on one actor, own the component instead of spawning per event:
Lifecycle Control
Setting User Parameters
Setters take an FName including the namespace prefix. They are silent no ops when the name or the type does not match the asset.
Namespace prefix Settable from C++
User. Yes — the only runtime overridable namespace
System. No — engine owned (Age, DeltaTime, ExecutionState)
Emitter. No — per emitter simulation state
Particle. No — per particle simulation state
Module. No — private to a stack node
Full C++ to Niagara type table, the array function library matrix and the pool method values are in [niagara parameter types.md](references/niagara parameter types.md).
Data Interfaces
Data interfaces are UNiagaraDataInterface subclasses exposed as User. parameters of DI type. Bind them with the typed helpers in UNiagaraFunctionLibrary , which take the parameter name as const FString& .
Array DIs are the workhorse for pushing gameplay data per frame. These helpers take FName :
Fetch a DI object when you need to mutate it directly:
The non template overload GetDataInterface(UClass DIClass, UNiagaraComponent , FName) covers the case where the class is only known at runtime. The built in DI catalogue with header paths, properties and sim target support is in [niagara data interfaces.md](references/niagara data interfaces.md).
Custom Data Interfaces
Subclass UNiagaraDataInterface ( NiagaraDataInterface.h ). The function list is editor only data: the override is GetFunctionsInternal(TArray<FNiagaraFunctionSignature & OutFunctions) const declared inside if WITH EDITORONLY DATA , plus GetVMExternalFunction to bind the CPU implementations and Equals / CopyToInternal so instances compare and duplicate correctly. GPU support adds ProvidePerInstanceDataForRenderThread and PerInstanceDataPassedToRenderThreadSize . Full class template in [niagara data interfaces.md](references/niagara data interfaces.md).
Niagara Data Channels
Data Channels are the supported bridge between gameplay code and Niagara, and between independent systems. A channel is a UNiagaraDataChannelAsset describing a payload; writers publish elements, Niagara emitters and game code read them.
Reading back on the game side:
SubscribeToNiagaraDataChannel(WorldContextObject, Channel, SearchParams, UpdateDelegate, UnsubscribeToken) pushes an FOnNewNiagaraDataChannelPublish callback whenever new elements are published; its FNiagaraDataChannelUpdateContext carries Reader , FirstNewDataIndex , LastNewDataIndex and NewElementCount . Pair every subscription with UnsubscribeFromNiagaraDataChannel using the stored token.
UNiagaraDataChannelLibrary also offers GetDataChannelElementCount , single element ReadFromNiagaraDataChannelSingle / WriteToNiagaraDataChannelSingle , and WithContext variants that take an FNDCAccessContextInst instead of FNiagaraDataChannelSearchParameters . The search parameter overloads are the legacy path and do not support newer channel types; prefer the context variants for new channels.
Completion Callbacks
OnSystemFinished is DECLARE DYNAMIC MULTICAST DELEGATE OneParam(FOnNiagaraSystemFinished, class UNiagaraComponent , PSystem) , so the handler must be a UFUNCTION() declared in a class body.
Simulation Caches
A UNiagaraSimCache records simulation frames and plays them back deterministically — useful for cinematics, network visible hero effects and regression tests.
UNiagaraSimCache exposes IsCacheValid() , CanRead(UNiagaraSystem ) , GetNumFrames() , GetStartSeconds() and GetDurationSeconds() . Data interfaces that hold their own state participate through INiagaraSimCacheCustomStorageInterface .
Lightweight Emitters
Emitters come in two modes, reported by FNiagaraEmitterHandle::GetEmitterMode() : ENiagaraEmitterMode::Standard ( UNiagaraEmitter , full scripted simulation) and ENiagaraEmitterMode::Stateless ( UNiagaraStatelessEmitter , a fixed cost analytic emitter with no per particle simulation buffers). Stateless emitters are authored in the Niagara editor and cost far less on CPU and memory; prefer them for ambient, high instance count effects.
UNiagaraStatelessEmitter lives in the module internal Internal/Stateless/NiagaraStatelessEmitter.h , so game modules cannot include it. Drive stateless emitters the same way as any other system — through UNiagaraComponent and User. parameters. To detect them from game code, read bIsLightweight on FNiagaraMinimalEmitterInfo from UNiagaraFunctionLibrary::GetAllEmitters .
Component Pooling
ENCPoolMethod on every spawn call selects pool behavior: None (fresh component), AutoRelease (returned automatically on completion; do not keep the pointer past the spawning tick) and ManualRelease (you call ReleaseToPool() ). ManualRelease OnComplete and FreeInPool are hidden internal states.
Pool capacity is a per system property on the asset ( MaxPoolSize , PoolPrimeSize on UFXSystemAsset , Particles/ParticleSystem.h:126,135 ); priming creates min(PoolPrimeSize, MaxPoolSize) components and PoolPrimeSize defaults to 0, so set it or priming is a no op ( NiagaraComponentPool.cpp:285 ). Global CVars: FX.NiagaraComponentPool.Enable , FX.NiagaraComponentPool.KillUnusedTime , FX.NiagaraComponentPool.CleanTime , FX.NiagaraComponentPool.Validation .
Scalability and Tick Behavior
ENiagaraTickBehavior Meaning
UsePrereqs Tick after attachment and data interface prerequisites. Safest, and the default.
UseComponentTickGroup Ignore prerequisites; use the component's own tick group.
ForceTickFirst Tick in the first tick group.
ForceTickLast Tick in the last tick group.
Scalability lives in the UNiagaraEffectType assigned to the system: SystemScalabilitySettings , EmitterScalabilitySettings , CullReaction , UpdateFrequency and an instanced SignificanceHandler . It is data driven; no per platform C++.
CPU vs GPU sim : CPU simulations support every data interface and can be read back; GPU simulations scale to far higher counts but support a narrower DI set and cannot be read back without an explicit readback path.
Determinism : for effects that must match across clients, enable fixed tick on the UNiagaraSystem asset ( bFixedTickDelta / FixedTickDeltaTime , readable through HasFixedTickDelta() and GetFixedTickDeltaTime() ) and use CPU simulation. Cosmetic effects belong on clients only — guard spawns with IsRunningDedicatedServer() .
Occlusion : SetOcclusionQueryMode(ENiagaraOcclusionQueryMode) / GetOcclusionQueryMode() control occlusion queries per component ( Default , AlwaysEnabled , AlwaysDisabled ).
Niagara Fluids (Beta in 5.8) adds GPU fluid and gas solvers at a high per frame cost; restrict it to hero effects.
Build Setup
"NiagaraCore" is only needed when you derive from UNiagaraDataInterface . Headers under Internal/ (for example Internal/DataInterface/NiagaraDataInterfaceStaticMesh.h ) are not includable from game modules.
Deprecated — do not use
Do not emit Use in 5.8 Source
SetNiagaraVariableFloat(const FString&, float) and every other SetNiagaraVariable FString setter SetVariableFloat(FName, float) and the matching SetVariable FName setters UE DEPRECATED(5.3) in Public/NiagaraComponent.h
UNiagaraDataInterface::GetFunctions(TArray<FNiagaraFunctionSignature &) GetFunctionsInternal(TArray<FNiagaraFunctionSignature &) const inside if WITH EDITORONLY DATA UE DEPRECATED(5.4) in Classes/NiagaraDataInterface.h
UNiagaraDataInterface::RequiresDistanceFieldData() RequiresGlobalDistanceField() UE DEPRECATED(5.4) in Classes/NiagaraDataInterface.h
UNiagaraDataInterface::ReadsEmitterParticleData(const FString&) GetEmitterReferencesByName() UE DEPRECATED(5.4) in Classes/NiagaraDataInterface.h
UNiagaraDataInterface::PostCompile() with no arguments the PostCompile overload taking the owning system UE DEPRECATED(5.7) in Classes/NiagaraDataInterface.h
UNiagaraDataInterface::IsUsedByCPUEmitter() / IsUsedByGPUEmitter() IsUsedWithCPUScript() / IsUsedWithGPUScript() UE DEPRECATED(5.3) in Classes/NiagaraDataInterface.h
UNiagaraComponent::GetSystemInstance() GetSystemInstanceController() UE DEPRECATED(5.0) in Public/NiagaraComponent.h
An abstract or submix named audio data interface base class UNiagaraDataInterfaceAudioSpectrum or UNiagaraDataInterfaceAudioOscilloscope , each with a USoundSubmix Submix property only three concret