This page provides an overview of Godot's animation system: how animations are stored as resources, how AnimationMixer resolves scene node paths and applies weighted track values each frame, and how AnimationPlayer and AnimationTree extend the mixer for sequential and graph-based playback respectively.
For detailed documentation on AnimationPlayer internals and the AnimationMixer track application pipeline, see AnimationPlayer & AnimationMixer. For the AnimationTree node graph, blend spaces, and state machines, see AnimationTree & AnimationNodes.
The system is structured in three layers:
| Layer | Classes | Location |
|---|---|---|
| Data | Animation, AnimationLibrary | scene/resources/ |
| Mixing base | AnimationMixer | scene/animation/animation_mixer.h |
| Playback | AnimationPlayer, AnimationTree | scene/animation/ |
Animation resources hold tracks and keys. AnimationLibrary groups them by name. AnimationMixer holds libraries, caches resolved scene-tree node references, and applies weighted animation values each frame. AnimationPlayer and AnimationTree both inherit from AnimationMixer and implement different strategies for producing per-frame animation instances.
Class Hierarchy
Sources: scene/animation/animation_mixer.h1-100 scene/animation/animation_player.h36-251 scene/animation/animation_tree.h43-250 scene/resources/animation.h38-120
Both AnimationPlayer and AnimationTree produce animation instances by overriding _blend_pre_process. The base AnimationMixer then evaluates those instances and writes values to target scene nodes.
Per-Frame Data Flow
Sources: scene/animation/animation_mixer.cpp430-600 scene/animation/animation_player.cpp160-302 scene/animation/animation_tree.cpp641-720 scene/animation/animation_blend_tree.cpp141-145
Animation (scene/resources/animation.h38-500) is a Resource subclass with no scene-tree awareness. It stores an ordered array of Track* pointers and metadata such as length, step, and loop_mode.
Each track holds a NodePath targeting a node (and optionally a property subpath), plus a sorted array of time-stamped keys.
| Enum Constant | Internal Struct | Payload |
|---|---|---|
TYPE_VALUE | ValueTrack | Any Variant; general property assignment |
TYPE_POSITION_3D | PositionTrack | Vector3; hardware-compressible |
TYPE_ROTATION_3D | RotationTrack | Quaternion; hardware-compressible |
TYPE_SCALE_3D | ScaleTrack | Vector3; hardware-compressible |
TYPE_BLEND_SHAPE | BlendShapeTrack | float; hardware-compressible |
TYPE_METHOD | MethodTrack | Method name + Variant args |
TYPE_BEZIER | BezierTrack | Single float with in/out bezier handles |
TYPE_AUDIO | AudioTrack | AudioStream reference + start/end offsets |
TYPE_ANIMATION | AnimationTrack | StringName animation key; triggers child AnimationPlayer |
The compressible track types (POSITION_3D, ROTATION_3D, SCALE_3D, BLEND_SHAPE) use a page-based bitwidth compression scheme stored in the Animation::Compression struct. Compressed tracks can only use INTERPOLATION_LINEAR and cannot be manually removed — the animation must be cleared first.
ValueTrack has an UpdateMode that controls when the property is written:
| Constant | Behavior |
|---|---|
UPDATE_CONTINUOUS | Interpolated every frame |
UPDATE_DISCRETE | Snaps to the most recent key |
UPDATE_CAPTURE | Captures the current live property value as a blend source when the animation starts |
Set per-track via InterpolationType:
| Constant | Description |
|---|---|
INTERPOLATION_NEAREST | Nearest-key snap |
INTERPOLATION_LINEAR | Linear between keys |
INTERPOLATION_CUBIC | Cubic Hermite |
INTERPOLATION_LINEAR_ANGLE | Linear with angular wrapping |
INTERPOLATION_CUBIC_ANGLE | Cubic with angular wrapping |
| Constant | Behavior |
|---|---|
LOOP_NONE | Clamps at end |
LOOP_LINEAR | Wraps back to start |
LOOP_PINGPONG | Reverses direction at each endpoint |
Animation stores named time markers in marker_names (sorted LocalVector<MarkerKey>) and marker_times (HashMap<StringName, double>). AnimationPlayer::play_section_with_markers uses these to set a playback window without modifying the animation data.
Sources: scene/resources/animation.h48-250 scene/resources/animation.cpp896-944
AnimationLibrary (scene/resources/animation_library.h) is a Resource holding a HashMap<StringName, Ref<Animation>>. Multiple libraries can be registered on a mixer. When a library has a non-empty name lib_name, its animations are addressed as "lib_name/anim_name". The default library (empty name) is addressed as just "anim_name".
AnimationMixer (scene/animation/animation_mixer.h42-300) is a Node that manages animation libraries, caches resolved scene-tree paths, and applies blended animation values each frame. It does not implement a playback strategy itself — that is delegated to AnimationPlayer or AnimationTree via virtual overrides.
animation_libraries — sorted LocalVector<AnimationLibraryData>, each entry holding a StringName name and a Ref<AnimationLibrary>.animation_set — a flat HashMap<StringName, AnimationData> rebuilt by _animation_set_cache_update() whenever a library changes. Each AnimationData holds the resolved Ref<Animation> and library membership.AnimationLibrary (animation_added, animation_removed, animation_renamed, animation_changed) drive automatic cache invalidation.Before applying any tracks, AnimationMixer resolves NodePath references from each Animation's tracks to actual Object* pointers and stores them in track_cache. This avoids per-frame path traversal. The cache is invalidated (_clear_caches()) when animations or libraries change.
| Property | Enum | Values |
|---|---|---|
callback_mode_process | AnimationCallbackModeProcess | PHYSICS, IDLE, MANUAL |
callback_mode_method | AnimationCallbackModeMethod | DEFERRED, IMMEDIATE |
callback_mode_discrete | AnimationCallbackModeDiscrete | DOMINANT, RECESSIVE, FORCE_CONTINUOUS |
MANUAL process mode disables automatic ticking; callers must invoke advance(delta) explicitly. callback_mode_method controls whether TYPE_METHOD track calls are deferred or immediate. callback_mode_discrete controls how UPDATE_DISCRETE value tracks interact with blending.
If root_motion_track is set to a NodePath referencing a 3D position or rotation track, the mixer accumulates that track's delta each frame and exposes it via get_root_motion_position() and get_root_motion_rotation() rather than writing it to the node directly. RootMotionView (scene/animation/root_motion_view.h) is an editor-only helper node for visualizing this output.
Sources: scene/animation/animation_mixer.cpp153-420 scene/animation/animation_mixer.h42-300
AnimationPlayer (scene/animation/animation_player.h36-257) extends AnimationMixer with sequential, crossfade-capable animation playback.
Internal state:
playback.current — a PlaybackData struct holding the active animation name, playback position, per-animation speed scale, and optional section start_time/end_time.playback.blend — a List<Blend> of outgoing animations fading out during a crossfade; each has a blend_left countdown and a copy of its PlaybackData.blend_times — HashMap<BlendKey, double> mapping {from, to} animation name pairs to crossfade durations.playback_queue — List<StringName> of animations to play in sequence._blend_pre_process overrides the base to call _blend_playback_data, which invokes _process_playback_data for the current animation and each blending animation, registering them with make_animation_instance.
Key API:
play(name, custom_blend, custom_speed, from_end) — start with optional crossfadeplay_section(name, start_time, end_time, ...) / play_section_with_markers(...) — time-windowed playbackpause() / stop(keep_state) — suspend or resetqueue(name) — enqueue for sequential playbackseek(time, update) — jump to positionset_autoplay(name) — play on NOTIFICATION_READYFor full detail on blend processing and the playback state machine, see AnimationPlayer & AnimationMixer.
Sources: scene/animation/animation_player.cpp160-378 scene/animation/animation_player.h52-140
AnimationTree (scene/animation/animation_tree.h160-280) extends AnimationMixer and drives animation via a directed graph of AnimationNode resources. Rather than a linear queue of named clips, the graph evaluates continuously and produces weighted animation instances each frame.
root_animation_node is a Ref<AnimationRootNode> that serves as the entry point of the graph. Each frame, _blend_pre_process calls root_animation_node->_pre_process(process_state, playback_info), which recursively walks the graph. Leaf nodes (AnimationNodeAnimation) call blend_animation() which calls make_animation_instance() back on the tree.
property_map is a flat map of all AnimationNode parameters, addressable from script as animation_tree["parameters/NodeName/param_name"].
For detail on the node graph and built-in node types, see AnimationTree & AnimationNodes.
AnimationNode (scene/animation/animation_tree.h43-250) is a Resource subclass that represents a single unit in the blend graph.
Key structures:
| Struct | Purpose |
|---|---|
NodeTimeInfo | Per-frame result: length, position, delta, loop_mode, will_end |
NodeState | Per-node transient state: base_path, parent, connections, track_weights |
ProcessState | Passed tree-wide during evaluation: pointer to AnimationTree, track_map, validation state |
Key methods:
blend_animation(name, PlaybackInfo) — registers a weighted animation instance with the mixerblend_node(node, subpath, info, filter, sync, test_only) — propagates playback to a sub-node, multiplying track weightsblend_input(input_index, info, filter, sync, test_only) — same, but resolves the sub-node via the input port index and a AnimationNodeBlendTreeFiltering: each node has a filter map (AHashMap<NodePath, bool>) and a FilterAction mode:
| FilterAction | Effect on filtered tracks |
|---|---|
FILTER_IGNORE | Filter map not consulted |
FILTER_PASS | Only filtered tracks receive weight |
FILTER_STOP | Filtered tracks receive zero weight |
FILTER_BLEND | Filtered tracks receive weighted blend; others pass through unweighted |
AnimationNode subclass hierarchy:
Roles of built-in node types:
| Class | File | Description |
|---|---|---|
AnimationNodeAnimation | animation_blend_tree.h | Leaf node; evaluates one named animation clip |
AnimationNodeBlendTree | animation_blend_tree.h | Container holding a sub-graph; exposes an Output node |
AnimationNodeBlend2 / Blend3 | animation_blend_tree.h | Blend two or three inputs by a blend float parameter |
AnimationNodeAdd2 / Add3 | animation_blend_tree.h | Additively mix two or three inputs |
AnimationNodeOneShot | animation_blend_tree.h | Fire a child animation once with fade-in/fade-out |
AnimationNodeTimeScale | animation_blend_tree.h | Scale the time of its input by a float parameter |
AnimationNodeTimeSeek | animation_blend_tree.h | Seek its input to a specific time |
AnimationNodeTransition | animation_blend_tree.h | Simple switch across N inputs with crossfade |
AnimationNodeStateMachine | animation_node_state_machine.h | Full state machine; states connected by AnimationNodeStateMachineTransition |
AnimationNodeBlendSpace1D | animation_blend_space_1d.h | Blend animations along a 1D axis by a float parameter |
AnimationNodeBlendSpace2D | animation_blend_space_2d.h | Blend animations in 2D space using barycentric coordinates |
Sources: scene/animation/animation_tree.h43-250 scene/animation/animation_blend_tree.h36-400 scene/animation/animation_node_state_machine.h37-200 scene/animation/animation_blend_space_1d.h1-100 scene/animation/animation_blend_space_2d.h1-100
AnimationNodeStateMachine holds named AnimationRootNode states connected by AnimationNodeStateMachineTransition resources. Playback is controlled through an AnimationNodeStateMachinePlayback object exposed as an AnimationTree parameter (typically accessed as animation_tree["parameters/StateMachine/playback"]).
Transition properties:
| Property | Type | Description |
|---|---|---|
switch_mode | SwitchMode | IMMEDIATE, SYNC, or AT_END |
advance_mode | AdvanceMode | DISABLED, ENABLED (manual), AUTO (condition-driven) |
advance_condition | StringName | Boolean parameter name that triggers AUTO advance |
advance_expression | String | GDScript expression evaluated for AUTO advance |
xfade_time | float | Crossfade duration in seconds |
xfade_curve | Ref<Curve> | Optional easing curve for the crossfade |
priority | int | Used to resolve competing transitions |
reset | bool | Whether to seek the destination state to 0 on entry |
AnimationNodeStateMachinePlayback methods: travel(state, reset_on_teleport), start(state, reset), stop(), next().
State machines can be nested. A state machine with STATE_MACHINE_TYPE_GROUPED is designed to be embedded inside a parent state machine, using virtual Start and End states to link entry/exit transitions.
Sources: scene/animation/animation_node_state_machine.h37-200 scene/animation/animation_node_state_machine.cpp197-340
| File | Contents |
|---|---|
scene/resources/animation.h/.cpp | Animation resource, all Track subtypes, interpolation, compression |
scene/resources/animation_library.h/.cpp | AnimationLibrary resource |
scene/animation/animation_mixer.h/.cpp | AnimationMixer base node; library management, track cache, blending pipeline |
scene/animation/animation_player.h/.cpp | AnimationPlayer; sequential playback, crossfade, queue |
scene/animation/animation_tree.h/.cpp | AnimationTree, AnimationNode, AnimationRootNode; graph evaluation |
scene/animation/animation_blend_tree.h/.cpp | AnimationNodeBlendTree and built-in blend/add/utility nodes |
scene/animation/animation_blend_space_1d.h/.cpp | AnimationNodeBlendSpace1D |
scene/animation/animation_blend_space_2d.h/.cpp | AnimationNodeBlendSpace2D; barycentric triangle blending |
scene/animation/animation_node_state_machine.h/.cpp | AnimationNodeStateMachine, AnimationNodeStateMachineTransition, AnimationNodeStateMachinePlayback |
scene/animation/root_motion_view.h/.cpp | RootMotionView editor visualization node |
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.