Everything you have animated on this island moves as one rigid piece. MoveTo slid whole props across South Shores, ease curves in North Jungle made those slides feel alive, the prop_mover device did it code-free in East Volcano, and the keyframed movement component swam scene-graph entities along authored deltas. But open up the Athenaeum guardian's model and you find something none of those tools can touch: a skeleton. Bones, joints, a bind pose — and a set of baked animation clips (a swim cycle, an idle sway) that were authored bone-by-bone in a DCC tool and imported with the mesh. Playing those clips at the right moment, from Verse, is this lesson. Re-posing the bones yourself is the next one (Control Rig). One rung at a time.
What you will build
The Athenaeum guardian's living-creature layer for the Sunken Athenaeum capstone: the guardian holding its post with a looping idle sway, then switching to its swim cycle the moment its patrol begins, and settling back to the sway when the patrol ends. The patrol itself is driven by the exact prop_mover you configured in East Volcano — the mover carries the guardian's patrol sled through the drowned stacks, and its BeganEvent/FinishedEvent become the guardian's animation cues. Body motion from the mover, bone motion from skeletal playback: two layers, cleanly separated. This is precisely the piece the capstone imports — and the piece the Control Rig lesson (next) takes over when the guardian graduates from baked clips to keyframed performances.
The scene-graph view: what a skeleton is to an entity
When you drag a skeletal mesh from the Content Browser onto a scene-graph entity, the editor attaches a mesh_component to that entity — the same component type that renders static meshes, now carrying a skeleton. Verse can find and manage that component, but you should know exactly where the public surface ends:
mesh_componentis marked<epic_internal>— you cannot construct one in code or subclass it. The editor attaches it; Verse works with what is there.- What you can do from Verse:
Entity.GetComponent[mesh_component], thenEnable()/Disable(), toggleVisible,Collidable,Queryable, and listen toEntityEnteredEvent/EntityExitedEventfor overlaps. - What you cannot do (yet): tell a
mesh_component"play clip X." There is an entity-level door —PlaySkeletalAnimation— but it is@experimental: projects using it cannot be published, andskeletal_animationvalues only exist as imported project assets. For reference, its real shape (do not ship this):
# @experimental -- compiles only with experimental features enabled,
# and experimental projects CANNOT be published. Shown for the map, not the trip.
using { /Verse.org/SceneGraph }
if (Result := Entity.PlaySkeletalAnimation[SwimClip]):
# Result.Easeable controls blending in/out via easing_window
Note what Epic is signalling with that signature: the ease-in/ease-out windows on PlaySkeletalAnimation are the same easing idea you learned with prop animation in North Jungle, applied to blending between skeletal clips. When this API matures, your ease instincts transfer directly.
So how do the pros ship skeletal animation today? Through the fully public, fully publishable door: the Animated Mesh device. You pick a skeletal mesh and one baked animation clip on the device in the editor, and Verse drives the transport — Play(), Pause(), PlayReverse(). One device, one mesh, one clip. Which sets up the central trick of this lesson: a guardian with two clips (swim + idle) needs two devices and a stage swap.
Walkthrough
Step 1 — Import the guardian's skeletal mesh and clips
In the Content Browser, import the guardian's skeletal mesh (FBX). UEFN brings the skeleton and its animation clips along for the ride — you should end up with the mesh, a skeleton asset, and (at least) two animation sequences: Guardian_Swim and Guardian_Idle. Double-click the skeletal mesh and open the Skeleton Tree tab to meet the bones you will be rigging by hand in the next lesson. Today, the baked clips do the posing.
Step 2 — Two Animated Mesh devices, one guardian
Place two Animated Mesh devices at the guardian's post in the Athenaeum, exactly overlapping:
- IdlePuppet — Skeletal Mesh: the guardian. Animation:
Guardian_Idle. Loop: on. - SwimPuppet — Skeletal Mesh: the guardian. Animation:
Guardian_Swim. Loop: on.
Same mesh, different clip. Only one puppet will ever be on stage (at the post) at a time — the other waits far below the seabed, where no diver will ever see it. Swapping which puppet occupies the stage is our clip switch. Theatre has used this trick for four hundred years; it still works underwater.
Step 3 — The patrol mover (your East Volcano import)
Place a Prop Mover device and aim it down the guardian's patrol lane through the drowned stacks, exactly the way you configured movers in East Volcano — target distance, target speed, the works. In the capstone this mover carries the guardian's patrol sled. The new idea: we stop treating the mover as the animation and start treating it as the cue source. Its BeganEvent means "the body is moving — swim," and its FinishedEvent means "the body has stopped — sway."
Step 4 — The Verse conductor
One device runs the whole swap. Complete and compilable:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Drives the Athenaeum guardian's baked skeletal clips:
# idle sway at its post, swim cycle while the patrol mover runs.
# Two Animated Mesh devices hold the SAME skeletal mesh with
# DIFFERENT clips; whichever is "on stage" is the guardian.
guardian_skeletal_animator := class(creative_device):
# Animated Mesh device: guardian mesh + Guardian_Swim clip (looping).
@editable
SwimPuppet : animated_mesh_device = animated_mesh_device{}
# Animated Mesh device: guardian mesh + Guardian_Idle clip (looping).
@editable
IdlePuppet : animated_mesh_device = animated_mesh_device{}
# The East Volcano skill, imported: the mover that drags the
# guardian's patrol sled through the drowned stacks.
@editable
PatrolMover : prop_mover_device = prop_mover_device{}
# How far below the stage the off-duty puppet waits, in cm.
@editable
OffstageDrop : float = 3000.0
# The guardian's post, captured at game start from IdlePuppet.
var Stage : transform = transform{}
OnBegin<override>()<suspends> : void =
# IdlePuppet starts at the post -- that spot IS the stage.
set Stage = IdlePuppet.GetTransform()
# Both clips run forever; being offstage is what hides a puppet.
# That keeps every swap instant -- no clip restart hitch.
IdlePuppet.Play()
SwimPuppet.Play()
# Idle owns the stage first: park the swimmer under the seabed.
SendOffstage(SwimPuppet)
# The mover's transport events are the animation cues.
# Both are listenable(tuple()) -- handlers take NO parameters.
PatrolMover.BeganEvent.Subscribe(OnPatrolBegan)
PatrolMover.FinishedEvent.Subscribe(OnPatrolFinished)
# Demo kick-off: let the sway read for a beat, then patrol.
# In the capstone, the relic ledger calls Begin() instead.
Sleep(5.0)
PatrolMover.Begin()
OnPatrolBegan() : void =
Print("Guardian: body in motion -- swim cycle on stage")
BringOnstage(SwimPuppet)
SendOffstage(IdlePuppet)
OnPatrolFinished() : void =
Print("Guardian: patrol done -- back to the idle sway")
BringOnstage(IdlePuppet)
SendOffstage(SwimPuppet)
# Teleport a puppet to the guardian's post.
BringOnstage(Puppet : animated_mesh_device) : void =
if (Puppet.TeleportTo[Stage]) {}
# Park a puppet far below the stage, out of sight.
SendOffstage(Puppet : animated_mesh_device) : void =
Below := vector3:
X := Stage.Translation.X
Y := Stage.Translation.Y
Z := Stage.Translation.Z - OffstageDrop
if (Puppet.TeleportTo[Below, Stage.Rotation]) {}
The pieces worth slowing down for:
- Two
animated_mesh_deviceslots, one skeleton. The device's public transport is exactly three calls —Play(),Pause(),PlayReverse()— and the clip is chosen in the editor, so clip switching becomes puppet switching. This is the honest, publishable shape of multi-clip skeletal playback today. - Both clips play forever. We never pause the off-stage puppet. A
Play()after aPause()resumes where it left off, which is great for scrubbing — but for a creature swap we want the incoming clip already mid-cycle, so the guardian never visibly "restarts" its swim. Parking a puppet 30 meters under the seabed is cheaper than any state machine. set Stage = IdlePuppet.GetTransform()— the stage is wherever you placed IdlePuppet in the editor. Move the guardian's post; the code follows.transformis a concrete struct, sotransform{}is a legal starting value until OnBegin captures the real one.PatrolMover.BeganEvent/FinishedEvent— both arelistenable(tuple()), so the handlers take no parameters (the same no-argument shape you will meet again on the sequencer'sStoppedEventnext lesson). The mover doesn't know it is conducting an animation system. It doesn't need to.TeleportTo[...]is failable — square brackets, wrapped inif. A teleport can fail (invalid destination, disposed object), and Verse makes you acknowledge that. The empty{}body is the idiomatic "success needs no celebration."
Step 5 — Wire it in the editor
- Place the
guardian_skeletal_animatordevice in the Athenaeum. - SwimPuppet → the Animated Mesh device holding
Guardian_Swim. - IdlePuppet → the Animated Mesh device holding
Guardian_Idle(this one sits at the guardian's post — its spot becomes the stage). - PatrolMover → the East Volcano-style mover aimed down the patrol lane.
Launch a session. Five seconds of sway, then the mover hums to life and the guardian is suddenly swimming — same skeleton, different bones firing. When the mover finishes, the sway returns like nothing happened.
Common patterns
Reveal the guardian through its mesh_component
The scene-graph half of this lesson in action: a component that finds the skeletal mesh's mesh_component on its own entity and manages visibility — the guardian materializes out of the murk when the simulation starts. GetComponent[mesh_component] is failable (the entity might not carry one), and note we manage the component the editor attached — we never construct one.
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
# Attach to the guardian's entity (the one carrying the skeletal mesh).
# Hides the mesh for a dramatic beat, then reveals it.
guardian_reveal_component := class<final_super>(component):
# Seconds of empty water before the guardian fades into view.
@editable
var RevealDelay<public> : float = 2.0
OnSimulate<override>()<suspends> : void =
if (Mesh := Entity.GetComponent[mesh_component]):
Mesh.Disable() # invisible, no collision, no queries
Sleep(RevealDelay)
Mesh.Enable() # the guardian is simply... there
PlayReverse: the wary retreat
The third transport call earns its keep on creatures. Play the swim clip backwards and the guardian appears to back away warily from a trespassing diver — one call, no new assets:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Trigger-driven scare reaction: swim backwards, then resume.
guardian_retreat_device := class(creative_device):
@editable
SwimPuppet : animated_mesh_device = animated_mesh_device{}
# Fires when a diver gets too close to the guardian's post.
@editable
ProximityTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
SwimPuppet.Play()
ProximityTrigger.TriggeredEvent.Subscribe(OnDiverClose)
# trigger_device.TriggeredEvent is listenable(?agent) --
# a trigger can fire with no instigator, hence the option.
OnDiverClose(Diver : ?agent) : void =
Print("Guardian recoils!")
SwimPuppet.PlayReverse()
spawn { ResumeForward() }
ResumeForward()<suspends> : void =
Sleep(2.0)
SwimPuppet.Play()
Where this goes next
The animation arc you have been climbing since South Shores now reads, in order: MoveTo → ease curves → prop_mover → skeletal playback → Control Rig. You just claimed the fourth rung — baked clips, played on cue.
Two destinations import this lesson directly:
control-rig-guardian-animation(next lesson) starts from the exact skeletal mesh you imported here. Baked clips are fixed — you cannot re-pose them — so the next lesson builds a Control Rig on the guardian's skeleton, keyframes the tentacle performances in Sequencer, and fires them from Verse. Your swim/idle layer keeps running for the guardian's everyday life; the rig takes over for the big moments.athenaeum-depths(the zone capstone) importsguardian_skeletal_animatorwhole: its relic ledger callsPatrolMover.Begin()when the vault stirs, and the swim/idle swap you built today is what makes the guardian read as alive while divers hunt relics beneath it.
Body by prop mover, bones by baked clips, performances by Control Rig — the guardian's whole existence, and you now own two-thirds of it.