MutableVFX

A reference implementation for feeding live, mutable gameplay data (an ability/technique’s timing and size info) into a Niagara VFX system via a custom Niagara Data Interface (NDI) — without needing to manually rewire Niagara User Parameters every time a new field is added.

Location: Source/FXImplementations/MutableVFX/

Why this exists

Niagara systems can read external data via User Parameters, but the naive approach — adding one User Parameter per value (Activation Time, Duration, Size, etc.) — means every time gameplay design wants to pass in a new field, someone has to add a new User Parameter in the Niagara editor and update every call site that sets it. It also doesn’t naturally support “live” data — values that change while the effect is already playing (e.g. an ability’s Duration getting extended mid-cast).

This system instead exposes one custom Niagara function (“Get Mutable VFX Info”) backed by a single struct. Gameplay code spawns the VFX and hands it a pointer to a small carrier object; the Niagara system reads through that pointer every frame, so whatever gameplay code does to the carrier’s data shows up in the running effect without any extra wiring.

How it works

Gameplay code (ability, designer BP, etc.)
        │
        │  builds FMutableVFXActivationInfo (transform, attach target, timing, size)
        ▼
UMutableVFXFunctionLibrary::SpawnMutableVFX()
        │
        │  spawns the Niagara component, creates a UMutableVFXInfoCarrier
        │  (outered to the spawned component so its lifetime matches the VFX),
        │  copies the activation info onto it, and sets it as the
        │  "User.MutableVFXObject" user parameter
        ▼
UNiagaraDataInterfaceMutableVFX (the NDI, set as that user parameter's value)
        │
        │  PerInstanceTick() (once per frame, game thread) re-reads
        │  Carrier->MutableVFXActivationInfo into its own per-instance cache
        ▼
Niagara graph — "Mutable VFX Query" node, "Get Mutable VFX Info" function
        │
        │  VectorVM function GetMutableVFXInfoVM() runs per particle-batch,
        │  writes the cached struct's fields out as individual float/vector pins
        ▼
Rest of the Niagara graph (artist-authored, uses the pins to drive the effect)

Usage

From C++ or Blueprint, call UMutableVFXFunctionLibrary::SpawnMutableVFX with a UNiagaraSystem* template and a filled-in FMutableVFXActivationInfo:

FMutableVFXActivationInfo Info;
Info.SpawnTransform = MyActor->GetActorTransform();
Info.AttachTarget = MyActor->GetMesh();
Info.ActivationTime = 0.2f;
Info.Duration = 2.5f;
Info.Size = FVector(1.5f, 1.5f, 1.5f);

UNiagaraComponent* VFX = UMutableVFXFunctionLibrary::SpawnMutableVFX(this, MyNiagaraSystem, Info);

On the Niagara side, any system using this pattern needs:

  1. A User Parameter of type UObject/Object Interface, named MutableVFXObject.
  2. A “Mutable VFX Query” Data Interface node bound to that user parameter.
  3. A “Get Mutable VFX Info” function call node off it, exposing 5 output pins: Activation Time, Duration, Launch Delay, Period, Size.

To update the live data mid-effect, keep a reference to the UMutableVFXInfoCarrier (not currently returned by SpawnMutableVFX — see Limitations below) and write to its MutableVFXActivationInfo fields directly; the running Niagara instance picks up the change on its next tick.

File structure

MutableVFXTypes.h

Plain data structs used throughout the system.