Builtin Library
- ..
- .metadata17 B
- Node.module
- README.md2.5 KB
- init.luau22.8 KB
- rigResolve.module
README.md
AnimGraph
DAG of animation nodes implemented in pure Luau. Nodes are stored in
a slot vector; freed slots are reused on the next addNode (mirrors
the legacy Rust crate's Vec<Option<AnimNode>> pattern). An AnimGraph
has exactly one designated "output" node. Each frame the engine calls
graph:update(dt) followed by graph:evaluate(), which recursively
walks reachable nodes and returns the pose buffer for the output node.
The module re-exports the Node hierarchy on the returned table so
callers can reach AnimGraph.Clip.new(...), AnimGraph.Mixer.new(...),
etc. without separate requires.
Exports
AnimGraph.new(opts: { layout: Layout? }?) -> AnimGraph— construct a new graph;layoutdefaults to a sensible default.AnimGraph:addNode(node: Node) -> number— insert a node, return its slot id (reuses freed slots).AnimGraph:removeNode(id: number)— free the node at slotidand call:destroy()on it.AnimGraph:setOutput(id: number)— designate which node is the graph's final output.AnimGraph:update(dt: number)— advance every reachable node.AnimGraph:evaluate() -> TypedBuffer?— return the output node's pose buffer (caller MUST NOT destroy).AnimGraph:crossfade(from: number, to: number, duration: number)— sugar that wires a temporary Mixer between two nodes, ramps weights overduration, then collapses to the new output when the ramp completes.AnimGraph.Clip,AnimGraph.Mixer,AnimGraph.BlendSpace2D,AnimGraph.Node— re-exports of the node constructors.
Types:
Layout = { ... }— pose layout used by the graph and its nodes.
Usage
local AnimGraph = require("@builtin::systems.anim.AnimGraph")
local graph = AnimGraph.new({ layout = myLayout })
local idle = graph:addNode(AnimGraph.Clip.new("idle"))
local walk = graph:addNode(AnimGraph.Clip.new("walk"))
graph:setOutput(idle)
graph:crossfade(idle, walk, 0.25) -- blend to walk over 250ms
-- Each frame:
graph:update(dt)
local pose = graph:evaluate()
Notes
- The output node MUST be set before
evaluateis called; otherwise the return value isnil. crossfadecollapses the temporary mixer when the ramp completes, so long-running graphs don't accumulate orphan mixers.- Buffer ownership: nodes own their internal buffers and free them in
:destroy(). Callers ofevaluateborrow the returned buffer — do NOT destroy it. removeNodefrees the slot id and calls:destroy()on the node; the nextaddNodemay reuse the same id.