Overview
A plain skeletal mesh placed in UEFN plays its assigned animation once and stays frozen — you can't touch it at runtime. The animated_mesh_device wraps that mesh with three live controls:
- Play — start or resume the animation forward.
- Pause — freeze the animation on the current frame.
- PlayReverse — start or resume the animation in reverse.
Use it any time you need an animation to respond to player actions: a vault door swinging open when a pressure plate is stepped on, a defeated boss collapsing when its health hits zero, or a rewind effect that plays a destruction sequence backwards.
API Reference
animated_mesh_device
Used to select, spawn, and configure a skeletal mesh to play a specific animation.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
animated_mesh_device<public> := class<concrete><final>(creative_device_base):
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Play |
Play<public>():void |
Starts or resumes playback of the animation. |
Pause |
Pause<public>():void |
Pauses playback of the animation. |
PlayReverse |
PlayReverse<public>():void |
Starts or resumes reverse playback of the animation. |
Walkthrough
Scenario: A Vault Door That Opens and Closes
A player steps on a trigger_device pressure plate to open a vault door (the animated mesh plays forward). Stepping on a second trigger plays the animation in reverse to close it. A third trigger pauses the door mid-swing — useful for a timed puzzle.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
# Place this device in your level, then wire up the three editable fields
# in the Details panel to your Animated Mesh Device and two Trigger Devices.
vault_door_controller := class(creative_device):
# The Animated Mesh Device driving the vault door skeletal mesh.
@editable
VaultDoor : animated_mesh_device = animated_mesh_device{}
# Trigger placed on the floor in front of the vault — opens the door.
@editable
OpenTrigger : trigger_device = trigger_device{}
# Trigger placed on the inside of the vault — closes the door.
@editable
CloseTrigger : trigger_device = trigger_device{}
# Trigger placed on a side panel — pauses the door mid-swing.
@editable
PauseTrigger : trigger_device = trigger_device{}
# Subscribe to all three triggers when the island starts.
OnBegin<override>()<suspends> : void =
OpenTrigger.TriggeredEvent.Subscribe(OnOpenTriggered)
CloseTrigger.TriggeredEvent.Subscribe(OnCloseTriggered)
PauseTrigger.TriggeredEvent.Subscribe(OnPauseTriggered)
# A player stepped on the open plate — play the animation forward.
# The handler receives ?agent because TriggeredEvent is listenable(?agent).
OnOpenTriggered(Agent : ?agent) : void =
VaultDoor.Play()
# A player stepped on the close plate — play the animation in reverse.
OnCloseTriggered(Agent : ?agent) : void =
VaultDoor.PlayReverse()
# A player hit the pause panel — freeze the door exactly where it is.
OnPauseTriggered(Agent : ?agent) : void =
VaultDoor.Pause()
Line-by-line breakdown
| Lines | What's happening |
|---|---|
@editable VaultDoor |
Exposes the animated mesh device slot in the Details panel so you can assign your placed device. |
@editable OpenTrigger / CloseTrigger / PauseTrigger |
Three pressure-plate triggers wired in the editor — no hard-coded names. |
OnBegin |
Runs at island start; subscribes each trigger's TriggeredEvent to a matching handler method. |
OnOpenTriggered |
Calls VaultDoor.Play() — starts or resumes forward playback. |
OnCloseTriggered |
Calls VaultDoor.PlayReverse() — starts or resumes reverse playback, closing the door. |
OnPauseTriggered |
Calls VaultDoor.Pause() — freezes the animation on the current frame. |
(Agent : ?agent) |
TriggeredEvent sends an optional agent; the handler signature must accept ?agent even if you don't use it here. |
Common patterns
Pattern 1 — Auto-play on island start (cinematic intro)
Some animations should just run the moment the island loads — a flag waving, a waterfall churning, an intro cinematic. Call Play() directly in OnBegin.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
auto_play_intro := class(creative_device):
# Animated mesh showing the intro cinematic skeletal mesh.
@editable
IntroCinematic : animated_mesh_device = animated_mesh_device{}
OnBegin<override>()<suspends> : void =
# Start the animation immediately when the island begins.
IntroCinematic.Play()
Pattern 2 — Pause then resume (timed puzzle gate)
A gate animation starts paused. When a player solves a puzzle (steps on a trigger), the gate resumes. A reset trigger pauses it again for the next attempt.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
puzzle_gate_controller := class(creative_device):
# The gate skeletal mesh device.
@editable
Gate : animated_mesh_device = animated_mesh_device{}
# Trigger fires when the puzzle is solved.
@editable
SolveTrigger : trigger_device = trigger_device{}
# Trigger fires when the puzzle resets.
@editable
ResetTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Pause immediately so the gate starts frozen.
Gate.Pause()
SolveTrigger.TriggeredEvent.Subscribe(OnSolved)
ResetTrigger.TriggeredEvent.Subscribe(OnReset)
OnSolved(Agent : ?agent) : void =
# Puzzle solved — resume the gate opening animation.
Gate.Play()
OnReset(Agent : ?agent) : void =
# Reset — freeze the gate again for the next attempt.
Gate.Pause()
Pattern 3 — Rewind effect (boss death sequence played in reverse)
A boss death animation plays forward on defeat. Stepping on a respawn trigger plays it in reverse so the boss "comes back to life" visually.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
boss_animation_controller := class(creative_device):
# Animated mesh for the boss skeletal mesh.
@editable
BossMesh : animated_mesh_device = animated_mesh_device{}
# Trigger fires when the boss is defeated.
@editable
DefeatTrigger : trigger_device = trigger_device{}
# Trigger fires when the boss respawns.
@editable
RespawnTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
DefeatTrigger.TriggeredEvent.Subscribe(OnBossDefeated)
RespawnTrigger.TriggeredEvent.Subscribe(OnBossRespawn)
OnBossDefeated(Agent : ?agent) : void =
# Play the collapse animation forward.
BossMesh.Play()
OnBossRespawn(Agent : ?agent) : void =
# Rewind the collapse — boss rises back up.
BossMesh.PlayReverse()
Gotchas
1. You MUST declare the device as an @editable field
You cannot call animated_mesh_device{} methods on a locally constructed value and expect it to control the placed device in your level. You must declare it as @editable inside your creative_device class and assign it in the UEFN Details panel. A bare animated_mesh_device{}.Play() compiles but controls nothing visible.
2. TriggeredEvent sends ?agent, not agent
trigger_device.TriggeredEvent is typed listenable(?agent). Your handler must accept (Agent : ?agent). If you need to use the agent (e.g., to grant an item), unwrap it first:
OnStepped(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
# A is now a concrete agent — safe to use
A.GetFortCharacter[].SetVulnerable()
Forgetting the ? causes a compile error.
3. Play and PlayReverse resume — they don't restart
Play() and PlayReverse() resume from the current frame, not from the beginning. If you need the animation to restart from frame 0, you need to design your animation asset to loop or use a separate trigger flow to reset state. There is no Stop() or Restart() on this device.
4. Skeletal meshes have no collision
As noted in Epic's documentation, skeletal meshes driven by animated_mesh_device do not collide with players, the world, or each other. A swinging door looks great but won't physically block a player — use invisible barrier devices alongside the animation if you need actual collision.
5. No built-in completion event
animated_mesh_device has no AnimationFinishedEvent. If you need to chain logic after an animation completes (e.g., lock the door after it fully closes), you must use a Sleep() call timed to match your animation's duration, or trigger a separate device from within Sequencer.