Overview
A transform is a lightweight struct that bundles three pieces of spatial information together: translation (where something is), rotation (which way it faces), and scale (how big it is). In Verse these are all value types — structs, not classes — so you copy them freely without worrying about references.
The companion type vector3 is a plain three-float struct (X, Y, Z) that represents a point or direction in Unreal's coordinate system. You'll encounter it constantly: GetViewLocation() on a fort_character returns a vector3, and the Translation field of a transform is also a vector3.
When do you reach for these?
- Checking whether a player is close enough to a treasure chest to unlock it.
- Logging where a player was standing when they triggered an alarm bell.
- Feeding a position into
TeleportToto move a device to a computed spot. - Comparing two positions to decide which team is winning a zone-control round.
Because transform and vector3 are pure data structs with no events of their own, you always use them in combination with something that fires an event — like a trigger_device stepped on by a player, or a fort_character's JumpedEvent.
API Reference
transform
A combination of scale, rotation, and translation, applied in that order.
Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse).
transform<native><public> := struct<concrete><computes>:
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. |
vector3
3-dimensional vector with
floatcomponents.
Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse).
vector3<native><public> := struct<concrete><computes><persistable><uht_comparable>:
Walkthrough
Scenario — The Lagoon Lookout Bell
Your cel-shaded pirate island has a lookout bell on the dock. When a player steps on the pressure plate next to it, you want to:
- Read the player's exact world position (their
fort_characterview location, avector3). - Print a flavour-text distance check to show how far they are from the island's centre anchor point (coordinates
0, 0, 0). - Ring the bell by calling
Trigger()on atrigger_devicewired to a sound/animation cue. - After ringing, disable the bell so it can only ring once per round.
This single example touches vector3 field reads, GetViewLocation(), trigger_device.Trigger(), trigger_device.Disable(), and trigger_device.SetMaxTriggerCount().
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Place this device in your level, then wire up the two @editable fields
# in the Details panel: a trigger_device for the pressure plate and a
# trigger_device wired to your bell sound/animation cue.
lagoon_lookout_bell := class(creative_device):
# The pressure plate the player steps on.
@editable
PressurePlate : trigger_device = trigger_device{}
# The bell trigger — wired to a sound cue or cinematic sequence.
@editable
BellTrigger : trigger_device = trigger_device{}
# The island's anchor point in world space (the dock centre).
# Adjust these values to match your island layout.
DockCentre : vector3 = vector3{X := 0.0, Y := 0.0, Z := 0.0}
OnBegin<override>()<suspends> : void =
# Allow the bell to ring only once per round.
BellTrigger.SetMaxTriggerCount(1)
# Subscribe to the pressure plate so we react when a player steps on it.
PressurePlate.TriggeredEvent.Subscribe(OnPlayerSteppedOnPlate)
# Called whenever an agent steps on the pressure plate.
OnPlayerSteppedOnPlate(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
# Cast agent -> fort_character to access spatial APIs.
if (Character := Agent.GetFortCharacter[]):
# GetViewLocation returns a vector3 — the eye/aim position.
PlayerPos : vector3 = Character.GetViewLocation()
# Read the individual float components of the vector3.
PX : float = PlayerPos.X
PY : float = PlayerPos.Y
PZ : float = PlayerPos.Z
# Compute a rough flat distance from the dock centre
# using the X and Y components only (ignore height).
DX : float = PX - DockCentre.X
DY : float = PY - DockCentre.Y
FlatDistSq : float = DX * DX + DY * DY
# Ring the bell — Trigger() fires TriggeredEvent on BellTrigger,
# which activates whatever is wired to it in Creative.
BellTrigger.Trigger()
# Disable the pressure plate so it cannot fire again this round.
PressurePlate.Disable()
Line-by-line explanation
| Lines | What's happening |
|---|---|
@editable PressurePlate |
Exposes a trigger_device slot in the Details panel so you can drag in the plate placed on the dock. |
@editable BellTrigger |
Exposes the bell's trigger device — wire it to a sound cue or Sequencer track in Creative. |
DockCentre : vector3 = vector3{X := 0.0, Y := 0.0, Z := 0.0} |
Constructs a vector3 literal — the island's world-space anchor. Change these floats to match your dock. |
BellTrigger.SetMaxTriggerCount(1) |
Caps the bell at one ring per round. 0 would mean unlimited. |
PressurePlate.TriggeredEvent.Subscribe(OnPlayerSteppedOnPlate) |
Hooks our handler to the plate's event. |
MaybeAgent : ?agent |
TriggeredEvent sends ?agent (optional), so we must unwrap it. |
if (Agent := MaybeAgent?) |
Unwraps the optional — skips the body if no agent triggered it (e.g. a code-side Trigger() call). |
Agent.GetFortCharacter[] |
Converts the agent to a fort_character so we can call spatial methods. The [] marks this as a failable expression. |
Character.GetViewLocation() |
Returns a vector3 — the eye/camera position of the character in world space. |
PlayerPos.X / .Y / .Z |
Reads the three float components of the vector3 struct directly. |
BellTrigger.Trigger() |
Fires the bell's TriggeredEvent, activating any Creative wiring (sounds, animations). |
PressurePlate.Disable() |
Prevents the plate from firing again until you re-enable it (e.g. at round start). |
Common patterns
Pattern 1 — Querying trigger limits before firing
Before ringing a second bell on the far side of the cove, check how many triggers remain so you don't waste a call on an exhausted device.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
cove_second_bell := class(creative_device):
@editable
FarBellTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Give the far bell a maximum of 3 rings total.
FarBellTrigger.SetMaxTriggerCount(3)
# Check how many rings are left before committing to one.
Remaining : int = FarBellTrigger.GetTriggerCountRemaining()
if (Remaining > 0):
FarBellTrigger.Trigger()
# Inspect the reset delay (how long before it can ring again).
Delay : float = FarBellTrigger.GetResetDelay()
# Delay is a float — use it in further logic as needed.
What's new here: SetMaxTriggerCount, GetTriggerCountRemaining, and GetResetDelay — three trigger_device methods that let you inspect and control the device's firing budget before pulling the trigger.
Pattern 2 — Adjusting timing: reset delay and transmit delay
Your pirate-ship cannon fires a salvo. You want a 5-second cooldown before it can fire again, and a 2-second delay before it signals the downstream explosion device.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
cannon_timing_controller := class(creative_device):
# The trigger wired to the cannon's firing sequence.
@editable
CannonTrigger : trigger_device = trigger_device{}
# A second trigger wired to the explosion VFX device.
@editable
ExplosionTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Cannon can fire unlimited times (0 = no limit).
CannonTrigger.SetMaxTriggerCount(0)
# 5-second cooldown between cannon shots.
CannonTrigger.SetResetDelay(5.0)
# The explosion device hears about the trigger 2 seconds later.
CannonTrigger.SetTransmitDelay(2.0)
# Subscribe so we can chain the explosion trigger manually too.
CannonTrigger.TriggeredEvent.Subscribe(OnCannonFired)
OnCannonFired(MaybeAgent : ?agent) : void =
# Fire the explosion trigger immediately from code
# (independent of the transmit delay on CannonTrigger).
ExplosionTrigger.Trigger()
What's new here: SetResetDelay, SetTransmitDelay, and GetTransmitDelay-style workflow — controlling the timing of a trigger device independently of when it fires.
Pattern 3 — Reading vector3 components to gate a zone
Only players standing on the sunny south shore (positive Y half of the map) can ring the victory bell. Read the character's position vector3 and check the Y component.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
south_shore_bell := class(creative_device):
@editable
Shoreplate : trigger_device = trigger_device{}
@editable
VictoryBell : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
Shoreplate.TriggeredEvent.Subscribe(OnShorePlateTriggered)
OnShorePlateTriggered(MaybeAgent : ?agent) : void =
if (Agent := MaybeAgent?):
if (Character := Agent.GetFortCharacter[]):
Pos : vector3 = Character.GetViewLocation()
# Only ring the bell if the player is on the south shore
# (Y > 0 in this island's coordinate layout).
if (Pos.Y > 0.0):
VictoryBell.Trigger()
else:
# Player is on the north side — disable the plate briefly.
Shoreplate.Disable()
# Re-enable after a short delay by re-subscribing next frame
# (a full Sleep-and-Enable loop would need a separate async task).
Shoreplate.Enable()
What's new here: Directly branching on a vector3 component (Pos.Y) to implement spatial zone logic — the core pattern for any position-gated mechanic.
Gotchas
1. transform and vector3 are structs — copy, don't mutate
transform and vector3 are struct types in Verse. That means they are value types: assigning one to a variable gives you a copy. There is no .SetX() method — to change a component you construct a new vector3 literal:
# WRONG — structs have no mutating methods
# MyPos.X = 100.0 -- does not compile
# RIGHT — construct a new vector3
NewPos : vector3 = vector3{X := 100.0, Y := MyPos.Y, Z := MyPos.Z}
2. Unwrap ?agent before using it
TriggeredEvent sends ?agent (an optional agent). If you forget to unwrap it with if (A := MaybeAgent?) your code will not compile — you cannot pass a ?agent where an agent is expected.
3. GetFortCharacter[] is failable — use if
Agent.GetFortCharacter[] uses the failable-expression bracket syntax []. Always call it inside an if or if (... := ...) block, or the compiler will reject it.
4. No automatic int ↔ float conversion
vector3 components are float. SetMaxTriggerCount takes int. Verse never auto-converts between the two. Use 1 (int literal) for trigger counts and 1.0 (float literal) for delays and positions — mixing them is a compile error.
5. SetMaxTriggerCount clamps to [0, 20]
Passing a value above 20 silently clamps to 20. Use 0 for truly unlimited triggers — GetTriggerCountRemaining() returns 0 in that case too, so don't use it as a "triggers left" check when the count is unlimited.
6. message vs string for any text you display
If you ever want to display position data as UI text, remember that Verse UI APIs require a message (localized), not a raw string. Declare a helper:
PosText<localizes>(S : string) : message = "{S}"
There is no StringToMessage function.
7. @editable fields are mandatory for placed devices
You cannot write trigger_device{}.Trigger() inline and expect it to affect a placed device. Every device you want to control must be declared as an @editable field and linked in the Details panel. A bare constructor trigger_device{} creates a disconnected default instance that does nothing in the world.