trigger_device: The Glue That Wires Player Actions to Events
The trigger_device is the humble workhorse of UEFN: a player steps on it (or your code pokes it), it fires a TriggeredEvent, and you chain that to anything — a vault door, a cinematic, a teleport. Learn it once and you'll reach for it in every map you build.
trigger_device in ~90 seconds.Overview
The trigger_device is a relay. Its whole job is to detect that something happened and then broadcast that fact so other things can react. The "something" is usually a player walking into its volume, but you can also fire it from Verse code with Trigger().
Reach for it whenever you want a player action to cause a consequence:
- Step on a pressure plate → open a vault door.
- Walk through a doorway → start a cinematic.
- Enter an arena → teleport every player into the action.
The device exposes one event you subscribe to — TriggeredEvent — and a handful of methods to drive it from code (Trigger), turn it on and off (Enable/Disable), and tune its behaviour (SetMaxTriggerCount, SetResetDelay, SetTransmitDelay). Because TriggeredEvent hands you the agent who triggered it, you can run player-specific logic — give that player a reward, teleport that character, and so on.
The key Verse rule to remember: you can't call methods on a placed device unless you declare it as an @editable field inside a class(creative_device), then point that field at the placed device in the UEFN Details panel.
API Reference
trigger_device
Used to relay events to other linked devices.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.
trigger_device<public> := class<concrete><final>(trigger_base_device):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
TriggeredEvent |
TriggeredEvent<public>:listenable(?agent) |
Signaled when an agent triggers this device. Sends the agent that used this device. Returns false if no agent triggered the action (ex: it was triggered through code). |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Trigger |
Trigger<public>(Agent:agent):void |
Triggers this device with Agent being passed as the agent that triggered the action. Use an agent reference when this device is setup to require one (for instance, you want to trigger the device only with a particular agent. |
Trigger |
Trigger<public>():void |
Triggers this device, causing it to activate its TriggeredEvent event. |
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
SetMaxTriggerCount |
SetMaxTriggerCount<public>(MaxCount:int):void |
Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20]. |
GetMaxTriggerCount |
GetMaxTriggerCount<public>()<transacts>:int |
Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count. |
GetTriggerCountRemaining |
GetTriggerCountRemaining<public>()<transacts>:int |
Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited. |
SetResetDelay |
SetResetDelay<public>(Time:float):void |
Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows). |
GetResetDelay |
GetResetDelay<public>()<transacts>:float |
Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows). |
SetTransmitDelay |
SetTransmitDelay<public>(Time:float):void |
Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
GetTransmitDelay |
GetTransmitDelay<public>()<transacts>:float |
Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered. |
Walkthrough
Let's build a classic: a pressure plate that opens a vault door. We place a trigger_device on the floor where the player steps, and a second trigger_device wired (via Direct Event Binding in UEFN, or in code) to the door — but to keep everything in Verse and self-contained, we'll just react to the step directly and give the triggering player a celebratory message, then disable the plate so it only works once.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Characters }
# Localized message helper — `message` params need a localizes value, not a raw string.
MyText<localizes>(S : string) : message = "{S}"
vault_room := class(creative_device):
# The pressure plate the player steps on. Point this at the placed trigger in UEFN.
@editable
PressurePlate : trigger_device = trigger_device{}
# A HUD message device to confirm the unlock (optional flavour).
@editable
UnlockMessage : hud_message_device = hud_message_device{}
OnBegin<override>()<suspends> : void =
# Only allow the plate to fire once, then stop reacting.
PressurePlate.SetMaxTriggerCount(1)
# Wait 0.5s after a trigger before the device tells other devices.
PressurePlate.SetTransmitDelay(0.5)
# Subscribe our handler to the event the plate fires when stepped on.
PressurePlate.TriggeredEvent.Subscribe(OnPlateStepped)
# TriggeredEvent hands us an OPTIONAL agent (?agent), because the device
# can also be triggered from code with no agent attached.
OnPlateStepped(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# We have a real player — confirm the vault is open just for them.
UnlockMessage.Show(Agent)
# Optional: react to their character (e.g. log position, etc.)
if (Char := Agent.GetFortCharacter[]):
Print("Player opened the vault!")
# Whether or not there was an agent, lock the plate down so it won't refire.
PressurePlate.Disable()
Line by line:
MyText<localizes>(...)— a helper so we could pass amessage; many message-taking APIs need localized text, never a rawstring.@editable PressurePlate : trigger_device = trigger_device{}— declares the field. After compiling, you select your placed plate in the device's Details panel. Without this field you cannot call any method on the plate.OnBegin<override>()<suspends>:void =— runs when the device starts in a live game.SetMaxTriggerCount(1)— clamps the plate so it fires at most once.SetTransmitDelay(0.5)— delays the outgoing signal by half a second (useful if you later wire it to a door via the device's bindings).TriggeredEvent.Subscribe(OnPlateStepped)— registers our method as the reaction. Subscriptions happen inOnBegin.OnPlateStepped(MaybeAgent : ?agent)— the handler. The parameter is?agent(optional!) because code-driven triggers send no agent.if (Agent := MaybeAgent?):— unwraps the option; the body only runs when a real player triggered it.UnlockMessage.Show(Agent)andAgent.GetFortCharacter[]— player-specific reactions.PressurePlate.Disable()— turns the device off so it stops reacting.
Common patterns
Fire a trigger from code to start a cinematic
You don't always wait for a player — sometimes your logic decides the moment. Here a different trigger is fired manually with Trigger(), which makes its own TriggeredEvent fire (with no agent). Wire that trigger to a cinematic in UEFN, and this code becomes your "play the cutscene now" button.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
cinematic_starter := class(creative_device):
# Plate the player walks through to enter the cutscene zone.
@editable
EntryPlate : trigger_device = trigger_device{}
# This trigger is wired to a cinematic_sequence_device in UEFN bindings.
@editable
CinematicTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
EntryPlate.TriggeredEvent.Subscribe(OnEntered)
OnEntered(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Pass the agent along so the cinematic trigger knows who started it.
CinematicTrigger.Trigger(Agent)
else:
# No agent (code path) — fire the agentless overload.
CinematicTrigger.Trigger()
Reusable plate with a cooldown and a budget
Use SetResetDelay for a cooldown between activations and SetMaxTriggerCount for a total budget. You can read the remaining budget with GetTriggerCountRemaining to react when the supply runs out.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
loot_dispenser := class(creative_device):
@editable
LootPlate : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Can be used 5 times total, with a 3-second cooldown between uses.
LootPlate.SetMaxTriggerCount(5)
LootPlate.SetResetDelay(3.0)
LootPlate.TriggeredEvent.Subscribe(OnLootGrabbed)
OnLootGrabbed(MaybeAgent : ?agent) : void =
Remaining := LootPlate.GetTriggerCountRemaining()
Print("Loot grabbed. Charges left: {Remaining}")
if (Remaining = 0):
# Budget exhausted — shut the dispenser down.
LootPlate.Disable()
Read configured delays back out
The getters let your logic stay in sync with whatever you set in the Details panel or in code. Here we mirror the plate's reset delay into a Sleep so a follow-up effect lines up perfectly.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
synced_plate := class(creative_device):
@editable
Plate : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
Plate.SetResetDelay(2.0)
Plate.TriggeredEvent.Subscribe(OnStepped)
OnStepped(MaybeAgent : ?agent) : void =
spawn{ WaitForReset() }
WaitForReset()<suspends> : void =
Delay := Plate.GetResetDelay()
Sleep(Delay)
Print("Plate is ready again after {Delay} seconds.")
Gotchas
TriggeredEventsends?agent, notagent. The device can be fired from code with no player, so the payload is optional. Always unwrap withif (Agent := MaybeAgent?):before using it. Trying to callAgent.GetFortCharacter[]on the raw?agentwon't compile.- You must have the
@editablefield, AND bind it in UEFN. A baretrigger_device{}field that you never point at a placed device will silently do nothing —Enable,Trigger, etc. operate on an unset device. SetMaxTriggerCountis clamped to [0,20]. Passing0means unlimited, not zero — andGetTriggerCountRemaining()returns0when the max is unlimited, so don't treat a0remaining as "empty" if you set the max to0.Trigger()vsTrigger(Agent). The agentless overload makesTriggeredEventfire withfalse/no agent; subscribers'?agentwill be empty. UseTrigger(Agent)when downstream logic needs to know who.- Subscribe in
OnBegin, not in a constructor. Event subscriptions must happen at runtime. Calling.Subscribeoutside the running device's lifecycle won't hook anything up. messageparams need localized text. If you call a method that takes amessage, use a<localizes>helper likeMyText("..."). There is noStringToMessage.- Verse never auto-converts int↔float.
SetResetDelaytakes afloat(2.0),SetMaxTriggerCounttakes anint(5). Mixing them up is a compile error.
Guides & scripts that use trigger_device
- Build Live Score Dashboards with Verse Player UILearn to bind gameplay metrics to on-screen widgets that update in real time for every player. This guide subscribes to a trigger event, computes a metric, and pushes a fresh text widget to each player's UI using the rea…
- Round-Persistent Survival Timers in VerseSurvival modes demand progress that survives round resets and server reloads. By pairing Verse's `<persistable>` classes with a module-scoped `weak_map`, you can track each player's survival time and mirror it on their s…
- Verse UI: Programmatic Widget Population with GetPlayerUILearn how to build a self-populating UI list in Verse by looping over a data array and injecting a text widget per entry. Using the real `GetPlayerUI[]` and `AddWidget` APIs, you can generate inventory rows, shop slots, …
- QUESTS API in Fortnite Creative/UEFN! (Experimental Tutorial)This tutorial demonstrates how to build a complete Quest Management system using Fortnite's experimental Verse Quests API. The creator walks through importing assets, defining custom quest classes inheriting from basic_q…
- Custom Vector Motion: Bypassing Keyframes in VerseStandard keyframed movement components consume significant memory and CPU cycles when animating dozens of objects. By calculating trajectories directly in Verse using vector math and concurrency primitives, you maintain …
- Driving Live HUD Widgets from Device Events in VerseBridge gameplay and interface by pushing runtime values into player HUD widgets. In this guide you subscribe to a trigger device, then update a real text_block on the player's UI canvas every time the trigger fires — a c…
Build your own lesson with trigger_device
Generate a personalized, compile-checked lesson grounded in this exact reference.
Build a lesson →