Overview
The crash_pad_device solves a specific creative problem: you want a surface that catapults players into the air, but you also want programmatic control over when that surface is active and what happens after a player hits it. Out of the box, a crash pad placed in UEFN just sits there and bounces anyone who lands on it. With Verse you can:
- Disable the pad at round start and Enable it only when a specific condition is met (a timer expires, a button is pressed, a zone is captured).
- Subscribe to
LaunchedEventto run logic the instant a player is launched — award points, trigger a cinematic, start a countdown, or disable the pad so it can only be used once.
Reach for crash_pad_device whenever your design needs bounce pads that are conditional, sequential, or reactive.
API Reference
crash_pad_device
Used to place a crash pad that can bounce players and protect them from fall damage.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
crash_pad_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
LaunchedEvent |
LaunchedEvent<public>:listenable(agent) |
Signaled when an agent is launched by this device. Sends the launched agent. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
Walkthrough
Scenario — One-Shot Launch Pad: A crash pad sits in the centre of an arena. It starts disabled. When a player steps on a trigger plate, the pad activates. The first player to land on it gets launched and the pad immediately disables itself — only one player gets the bounce per round.
one_shot_crash_pad_manager := class(creative_device):
# Wire these up in the UEFN Details panel
@editable
Pad : crash_pad_device = crash_pad_device{}
@editable
ActivationPlate : trigger_device = trigger_device{}
# Called when the island starts
OnBegin<override>()<suspends> : void =
# Start with the pad disabled — nobody bounces until the plate is hit
Pad.Disable()
# When a player steps on the trigger plate, enable the crash pad
ActivationPlate.TriggeredEvent.Subscribe(OnPlateTriggered)
# When a player is launched by the pad, disable it immediately
Pad.LaunchedEvent.Subscribe(OnPlayerLaunched)
# Handler: plate was triggered — enable the crash pad
OnPlateTriggered(TriggeringAgent : ?agent) : void =
Pad.Enable()
# Handler: a player was launched — disable so only one player gets the bounce
OnPlayerLaunched(LaunchedAgent : agent) : void =
# LaunchedEvent sends a non-optional agent, so no unwrap needed
Pad.Disable()
Line-by-line breakdown:
| Line | What it does |
|---|---|
@editable Pad |
Exposes the crash pad slot in the UEFN Details panel so you drag-and-drop your placed device. |
@editable ActivationPlate |
Same for the trigger plate that arms the pad. |
Pad.Disable() in OnBegin |
Ensures the pad is off at game start — no accidental early bounces. |
ActivationPlate.TriggeredEvent.Subscribe(OnPlateTriggered) |
Listens for any player stepping on the plate. |
Pad.LaunchedEvent.Subscribe(OnPlayerLaunched) |
Listens for the crash pad launching a player. |
OnPlateTriggered |
Receives a ?agent (optional) from TriggeredEvent — we only need to call Pad.Enable() so we don't need to unwrap the agent here. |
OnPlayerLaunched |
Receives a non-optional agent from LaunchedEvent. Calls Pad.Disable() to make this a one-shot pad. |
Common patterns
Pattern 1 — Track every launch and print the agent's name (LaunchedEvent + agent unwrap)
Subscribe to LaunchedEvent to keep a running count of how many times players have been launched. LaunchedEvent sends a plain agent (not ?agent), so no unwrap is needed — you can use it directly.
launch_counter_device := class(creative_device):
@editable
Pad : crash_pad_device = crash_pad_device{}
var LaunchCount : int = 0
OnBegin<override>()<suspends> : void =
Pad.LaunchedEvent.Subscribe(OnLaunched)
OnLaunched(LaunchedAgent : agent) : void =
set LaunchCount += 1
# LaunchedAgent is a plain agent — use it directly with any agent API
# e.g. award XP, update a HUD counter, etc.
# Here we just track the count; extend with your own game logic.
Pattern 2 — Timed enable/disable cycle (Enable + Disable in a loop)
Make the crash pad pulse on and off every few seconds — active for 3 seconds, dormant for 5. This creates a rhythm-based challenge where players must time their approach.
pulsing_pad_device := class(creative_device):
@editable
Pad : crash_pad_device = crash_pad_device{}
# How long the pad stays active (seconds)
ActiveDuration : float = 3.0
# How long the pad stays dormant (seconds)
DormantDuration : float = 5.0
OnBegin<override>()<suspends> : void =
# Loop forever, toggling the pad on and off
loop:
Pad.Enable()
Sleep(ActiveDuration)
Pad.Disable()
Sleep(DormantDuration)
Pattern 3 — Disable all pads when a round ends (Disable from an external event)
You have multiple crash pads scattered across the map. When a timer_device expires (round over), disable every pad at once so no late bounces occur.
round_end_pad_controller := class(creative_device):
@editable
RoundTimer : timer_device = timer_device{}
# Add as many pads as your map needs
@editable
Pad1 : crash_pad_device = crash_pad_device{}
@editable
Pad2 : crash_pad_device = crash_pad_device{}
@editable
Pad3 : crash_pad_device = crash_pad_device{}
OnBegin<override>()<suspends> : void =
RoundTimer.SuccessEvent.Subscribe(OnRoundEnd)
OnRoundEnd(CompletingAgent : ?agent) : void =
Pad1.Disable()
Pad2.Disable()
Pad3.Disable()
Gotchas
1. LaunchedEvent sends agent, not ?agent.
Unlike many device events (e.g. trigger_device.TriggeredEvent which sends ?agent), crash_pad_device.LaunchedEvent delivers a plain, non-optional agent. Do not try to unwrap it with if (A := Agent?) — that pattern is for ?agent parameters only. Just use the parameter directly.
2. Devices must be @editable fields — never bare identifiers.
Calling crash_pad_device{}.Enable() on a freshly constructed literal does nothing useful; it's not the device placed in your level. Always declare @editable Pad : crash_pad_device = crash_pad_device{} and wire it in the UEFN Details panel.
3. Disable() does not reset the pad's position.
If your design deploys crash pads dynamically (e.g. via a prop mover), disabling the device only stops it from bouncing players — it does not move or hide the mesh. Pair with a prop manipulator or visibility device if you need it to disappear.
4. Enable/Disable are not <suspends> — call them freely.
Both Enable() and Disable() are plain void methods with no effects. You can call them inside any handler or loop body without needing spawn or sync.
5. Subscribe in OnBegin, not in the constructor.
Event subscriptions must happen at runtime inside OnBegin<override>()<suspends>. Subscribing in a field initialiser or class body will not compile.