Overview
The vfx_spawner_device is the device you reach for whenever you want a visual effect to appear at a fixed spot in your level — a glowing portal, a campfire, a sparkle over an objective, a burst when a player wins a round. You pick the effect in the device's Details panel (including a Custom Visual Effect override for your own Niagara assets), and then drive when it plays from Verse.
The game problem it solves: most effects shouldn't just loop forever. You want the portal VFX to switch on only after a player unlocks it, the explosion burst to fire the moment a vault is cracked, or the heartbeat aura to reveal a hiding prop. The Verse surface is small and purpose-built for exactly that: Enable, Disable, and Restart, plus two events — EffectEnabledEvent and EffectDisabledEvent — that tell you when the effect actually turned on or off so you can chain more logic (sound, score, more VFX).
Reach for the VFX Spawner when the effect lives at a known location and you mainly need to toggle it. (If you need to spawn effects at arbitrary runtime positions or heavily customize parameters, that's the job of the vfx_creator_device instead.)
API Reference
(API surface could not be resolved for this device.)
Walkthrough
Let's build a classic "crack the vault" moment. A player steps on a pressure plate (a trigger_device). When they do, we enable a glowing portal VFX and, because it's set to a Burst effect, restart it so the burst plays from the top. When the round resets via a button, we disable the effect again. We also subscribe to EffectEnabledEvent so we can log/confirm the effect actually fired.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# A vault reveal: stepping on the plate fires a burst VFX; a reset button hides it.
vault_vfx_device := class(creative_device):
@editable
PortalVFX : vfx_spawner_device = vfx_spawner_device{}
@editable
PressurePlate : trigger_device = trigger_device{}
@editable
ResetButton : button_device = button_device{}
OnBegin<override>()<suspends>:void =
# Start with the effect hidden until the vault is cracked.
PortalVFX.Disable()
# Wire the pressure plate to turn the effect ON.
PressurePlate.TriggeredEvent.Subscribe(OnPlateStepped)
# Wire the reset button to turn the effect OFF.
ResetButton.InteractedWithEvent.Subscribe(OnResetPressed)
# React when the VFX confirms it actually enabled.
PortalVFX.EffectEnabledEvent.Subscribe(OnEffectEnabled)
# TriggeredEvent hands us a ?agent — the player who stepped on the plate.
OnPlateStepped(MaybeAgent : ?agent):void =
if (Agent := MaybeAgent?):
# Make the effect visible, then re-trigger the burst from the top.
PortalVFX.Enable()
PortalVFX.Restart()
# The reset button hides the effect again for the next round.
OnResetPressed(Agent : agent):void =
PortalVFX.Disable()
# EffectEnabledEvent payload is an empty tuple() — it just signals the moment.
OnEffectEnabled():void =
Print("Vault portal VFX is now live!")
Line by line:
- The three
@editablefields are how Verse gets a handle on the placed devices. After compiling, you select each one in the device's Details panel in UEFN. Without these fields you cannot call any method. OnBeginruns once when the game starts. We callPortalVFX.Disable()immediately so the portal isn't glowing before anyone earns it.PressurePlate.TriggeredEvent.Subscribe(OnPlateStepped)registers our handler.TriggeredEventis alistenable(?agent), so the handler receives a?agent— an optional agent.ResetButton.InteractedWithEvent.Subscribe(OnResetPressed)wires the button. The button's interact event hands a plainagent.PortalVFX.EffectEnabledEvent.Subscribe(OnEffectEnabled)lets us react to the device's own confirmation that the effect switched on.- In
OnPlateStepped, we unwrap the optional withif (Agent := MaybeAgent?). Even though we don't use the agent here, unwrapping is the safe pattern; only when we have a real player do weEnable()andRestart()the VFX. Restart()matters for Burst effects: enabling alone may not replay a burst that already fired, soRestart()guarantees a fresh playthrough.OnEffectEnabledtakes no parameters becauseEffectEnabledEventcarries an emptytuple()payload — it's a pure timing signal.
Common patterns
Pattern 1 — Toggle an ambient effect on a timer loop
Use Enable/Disable to pulse an effect on and off (e.g. a flickering magic fountain) using Sleep in a loop.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
pulsing_fountain_device := class(creative_device):
@editable
FountainVFX : vfx_spawner_device = vfx_spawner_device{}
OnBegin<override>()<suspends>:void =
loop:
FountainVFX.Enable()
Sleep(2.0) # effect visible for 2 seconds
FountainVFX.Disable()
Sleep(1.0) # hidden for 1 second
Pattern 2 — Re-fire a burst every time an item is collected
Subscribe to another device's event and call Restart() to replay a Burst VFX each pickup.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
collect_sparkle_device := class(creative_device):
@editable
SparkleVFX : vfx_spawner_device = vfx_spawner_device{}
@editable
Pickup : item_granter_device = item_granter_device{}
OnBegin<override>()<suspends>:void =
SparkleVFX.Enable()
Pickup.ItemReceivedEvent.Subscribe(OnItemReceived)
OnItemReceived(Agent : agent):void =
# Replay the burst from the top each time a player grabs the item.
SparkleVFX.Restart()
Pattern 3 — React to the disabled event to chain follow-up logic
Use EffectDisabledEvent to know exactly when an effect has finished switching off, then trigger the next stage.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
stage_chain_device := class(creative_device):
@editable
SmokeVFX : vfx_spawner_device = vfx_spawner_device{}
@editable
NextStageDoor : barrier_device = barrier_device{}
OnBegin<override>()<suspends>:void =
SmokeVFX.Enable()
SmokeVFX.EffectDisabledEvent.Subscribe(OnSmokeCleared)
OnSmokeCleared():void =
# Once the smoke screen is gone, drop the barrier so players can pass.
NextStageDoor.Disable()
Gotchas
- You must declare an
@editablefield and bind it in UEFN. Callingvfx_spawner_device{}.Enable()on a fresh literal does nothing useful — it's not the device you placed. The handle has to come from an@editablefield you assigned in the Details panel. EnablevsRestartfor Burst effects. A Burst VFX plays once. CallingEnable()when it's already enabled won't necessarily replay it. UseRestart()to force the burst to fire again. For looping effects,Enable/Disableis enough.EffectEnabledEvent/EffectDisabledEventcarry an emptytuple(), not an agent. Your handler must take no parameters (OnEffectEnabled():void =). Don't try to unwrap an agent from them.TriggeredEventislistenable(?agent)— the payload is optional. Always unwrap withif (Agent := MaybeAgent?):before using the agent; a trigger can fire without a specific instigator.- There is no per-agent visibility on this device's core API. Unlike some effect devices, the standard
vfx_spawner_deviceVerse surface (Enable,Disable,Restart) toggles the effect globally. If you need per-player effects (like the prop-hunt heartbeat), the established pattern is to place one VFX Spawner per player and teleport/toggle each individually. - Don't confuse it with
vfx_creator_device. The creator device has a different, richer API for fully custom runtime effects. The spawner is the simpler "pick an effect, toggle it" device — and its methods are exactly the ones shown above.