animation
The animation namespace — the engine's Luau API reference for animation.
The animation namespace — 9 functions.
globals/animation/animating
animation.animating() -> { AnimationBody }
The bodies the engine measured a changing pose on — what is animating right now.
Returns { AnimationBody } — An array of AnimationBody.
for _, b in animation.animating() do print(b.entity, b.clips[1] and b.clips[1].name) end
globals/animation/bodies
animation.bodies() -> { AnimationBody }
Every body the engine holds animation state for.
Returns { AnimationBody } — An array of AnimationBody.
for _, b in animation.bodies() do print(b.entity, b.matched .. "/" .. b.total) end
globals/animation/body
animation.body(entityId: string | EntityRef) -> AnimationBody?
The report for one body, or nil when the engine holds no animation state for it. Accepts the body itself or any ancestor of it, so a character root answers for the skinned body underneath it.
Parameters
entityIdstring | EntityRef— The entity's stable id, or an EntityRef.
Returns AnimationBody? — An AnimationBody, or nil.
local b = animation.body(hero.id); print(b and b.reason)
globals/animation/clips
animation.clips(entityId: string | EntityRef) -> { AnimationClip }
The clips contributing to a body's pose right now, with their playheads and their retarget coverage.
Parameters
entityIdstring | EntityRef— The entity's stable id, or an EntityRef.
Returns { AnimationClip } — An array of AnimationClip.
for _, c in animation.clips(hero.id) do print(c.name, c.time, c.matched) end
globals/animation/coverage
animation.coverage(entityId: string | EntityRef) -> (number, number)
How many of a body's bones the clips driving it actually reach.
Returns (matched, total). A clip that retargets onto nothing reads
(0, 50) while its playhead advances; a partial retarget reads its own
count, so 3 of 50 is as visible as none.
Parameters
entityIdstring | EntityRef— The entity's stable id, or an EntityRef.
Returns (number, number) — (matched, total).
local m, t = animation.coverage(hero.id); print(m .. "/" .. t)
globals/animation/declare
animation.declare(entityId: string, facts: { [string]: any })
Publish what an animator is running on a body, so the observation names
its clips, playheads and retarget coverage beside the pose the engine
measures. The shipped animators declare through AnimGraph:publish; a
custom animator calls this itself, once per frame it runs.
Parameters
entityIdstring— The body the animator drives.facts{ [string]: any }—{ driver, bound, playing, outputKind, failure, clips }, where each clip is{ name, nodeKind, time, duration, playing, finished, looping, weight, matched, total, unmatched }.
animation.declare(body.id, { driver = "MyAnimator", playing = true, clips = {} })
globals/animation/forget
animation.forget(entityId: string)
Drop the declaration and the pose evidence the engine holds for one body. An animator calls this when it releases a body, so the observation reports the body as undriven from the next frame.
Parameters
entityIdstring— The body to drop.
animation.forget(body.id)
globals/animation/observe
animation.observe() -> AnimationObservation
Report what the engine is posing right now and why a body is not moving. One read covering every body the engine holds animation state for, each with the pose evidence the engine measured on its armature beside the clips the animator driving it declared. Answers in edit mode as well as play mode.
Returns AnimationObservation — An AnimationObservation.
local a = animation.observe(); print(a.animatingCount, a.riggedBodyCount)
for _, b in animation.observe().bodies do print(b.entity, b.animating, b.reason) end
globals/animation/whyStill
animation.whyStill(entityId: string | EntityRef) -> (string?, string?)
Why the body on an entity is not animating. Returns nil when it IS
animating, and otherwise one of deactivated, noRiggedSkeleton,
noGraph, clipUnreadable, noOutputNode, retargetMatchedNoRoles,
stopped, finished, paused, poseNotApplied, poseUnchanged — the
nearest cause, so the answer names the thing to change. A second return
carries the animator's own words when it could not build a graph.
An entity the engine holds no animation state for is answered from the
entity itself, in the same order the engine resolves a body it does hold:
one carrying no rigged Skeleton is noRiggedSkeleton, and a rigged one
nothing drives is noGraph. An id no entity carries is neither — the
reason is nil and the detail says so.
Parameters
entityIdstring | EntityRef— The entity's stable id, or an EntityRef.
Returns (string?, string?) — (reason, detail).
local why, detail = animation.whyStill(hero.id); if why then print(why, detail) end