This page covers AnimationMixer, the base class for both AnimationPlayer and AnimationTree, and AnimationPlayer, which provides direct sequential animation playback. It includes the Animation resource format, animation libraries, the track system, blending mechanics, and the per-frame processing pipeline.
For the graph-based blending system built on top of AnimationMixer, see AnimationTree & AnimationNodes. For the overall animation system overview, see Animation System.
AnimationMixer is a Node subclass that acts as the shared infrastructure for managing animation libraries, resolving track targets, blending weighted animation instances, and writing the result to scene nodes. Both AnimationPlayer and AnimationTree extend it.
AnimationMixer class hierarchy
Sources: scene/animation/animation_mixer.h42-300 scene/animation/animation_player.h36-251 scene/animation/animation_tree.h170-250
Animation ResourceAn Animation (scene/resources/animation.h scene/resources/animation.cpp) is a Resource that stores time-keyed data across one or more tracks. Each track targets a scene node path and a specific property or behaviour.
| Enum Constant | Track Struct | Description |
|---|---|---|
TYPE_VALUE | ValueTrack | Animates any Variant property on a node |
TYPE_POSITION_3D | PositionTrack | Node3D position (compressed-capable) |
TYPE_ROTATION_3D | RotationTrack | Node3D rotation as Quaternion |
TYPE_SCALE_3D | ScaleTrack | Node3D scale |
TYPE_BLEND_SHAPE | BlendShapeTrack | MeshInstance3D blend shape weight |
TYPE_METHOD | MethodTrack | Calls a method on a node at a specific time |
TYPE_BEZIER | BezierTrack | Single-float property with bezier curve handles |
TYPE_AUDIO | AudioTrack | Plays an AudioStream at a time offset |
TYPE_ANIMATION | AnimationTrack | Triggers another named animation |
Sources: scene/resources/animation.h48-58
ValueTrack has an UpdateMode field controlling when its value is written:
| Mode | Behaviour |
|---|---|
UPDATE_CONTINUOUS | Interpolated every frame |
UPDATE_DISCRETE | Set only at keyframe times (nearest/exact) |
UPDATE_CAPTURE | Captures the current node value at play start, then blends to keyframes |
Sources: scene/resources/animation.h68-72
Animation::LoopMode applies to the whole animation:
| Mode | Behaviour |
|---|---|
LOOP_NONE | Stops at the end |
LOOP_LINEAR | Wraps from end back to start |
LOOP_PINGPONG | Reverses direction at each end |
Sources: scene/resources/animation.h74-79
Markers are named time points stored alongside tracks. They are used by AnimationPlayer to define sub-sections of an animation. Each marker has a StringName, a double time, and a display Color.
marker_names // LocalVector<MarkerKey> — sorted by time
marker_times // HashMap<StringName, double>
marker_colors // HashMap<StringName, Color>
Sources: scene/resources/animation.h248-250
AnimationMixer — Base ClassAnimationMixer (scene/animation/animation_mixer.h scene/animation/animation_mixer.cpp) manages the lifecycle of animation libraries, maintains a flat lookup of all animations, builds and caches resolved track targets, and drives the per-frame blend pipeline.
Animations are grouped into AnimationLibrary resources. Each library is registered with a StringName key. The default library uses an empty StringName. Animations in named libraries are accessed via "library_name/animation_name" composite keys; animations in the default library use just their own name.
Access keys in this example: "idle", "jump", "movement/run", "movement/walk".
The internal flat map animation_set (type AHashMap<StringName, AnimationData>) is rebuilt by _animation_set_cache_update() whenever libraries are added, removed, or their contents change. This function connects to signals animation_added, animation_removed, animation_renamed, and animation_changed on each library.
Key data structures:
struct AnimationLibraryData {
StringName name;
Ref<AnimationLibrary> library;
};
struct AnimationData {
StringName name;
StringName animation_library;
Ref<Animation> animation;
uint64_t last_update;
};
Sources: scene/animation/animation_mixer.h72-95 scene/animation/animation_mixer.cpp153-208 scene/animation/animation_mixer.cpp296-330
On first use (or after _clear_caches()), AnimationMixer resolves each track's NodePath to an actual node and property reference, stored in typed TrackCache subtypes. This avoids repeated node lookup and property resolution every frame.
| Cache Type | For Track Type |
|---|---|
TrackCacheTransform | TYPE_POSITION_3D, TYPE_ROTATION_3D, TYPE_SCALE_3D |
TrackCacheBlendShape | TYPE_BLEND_SHAPE |
TrackCacheValue | TYPE_VALUE, TYPE_BEZIER |
TrackCacheMethod | TYPE_METHOD |
TrackCacheAudio | TYPE_AUDIO |
TrackCacheAnimation | TYPE_ANIMATION |
The cache is invalidated by _clear_caches(), which is called on library changes, animation changes, and tree structure changes.
Sources: scene/animation/animation_mixer.cpp150-205
AnimationCallbackModeProcess controls which engine loop drives _process_animation():
| Mode | Signal Used |
|---|---|
ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS | NOTIFICATION_INTERNAL_PHYSICS_PROCESS |
ANIMATION_CALLBACK_MODE_PROCESS_IDLE | NOTIFICATION_INTERNAL_PROCESS |
ANIMATION_CALLBACK_MODE_PROCESS_MANUAL | None — caller invokes advance() |
AnimationCallbackModeMethod controls whether method tracks are called immediately or deferred:
| Mode | Behaviour |
|---|---|
ANIMATION_CALLBACK_MODE_METHOD_DEFERRED | call_deferred() |
ANIMATION_CALLBACK_MODE_METHOD_IMMEDIATE | Direct call |
Sources: scene/animation/animation_mixer.h54-70 scene/animation/animation_mixer.cpp430-455
AnimationMixer supports extracting root motion from a designated track via root_motion_track (a NodePath). When set, position/rotation/scale changes on that track are accumulated into root_motion_transform instead of being applied to the node directly. The result is read back via get_root_motion_position(), get_root_motion_rotation(), get_root_motion_scale(), and get_root_motion_transform(). The root_motion_local flag controls whether the transform is in local or global space.
Sources: scene/animation/animation_mixer.h140-160 scene/animation/animation_mixer.cpp
The UPDATE_CAPTURE value track update mode allows seamless blending from the current runtime state of a property into an animation. capture(animation_name, duration, trans_type, ease_type) snapshots current property values and stores them in an internal CaptureCache. During playback, captured values are blended toward the animation keyframes over the given duration.
AnimationPlayer adds auto_capture mode: when true, play() automatically calls the capture setup before starting the new animation, using configurable auto_capture_duration, auto_capture_transition_type, and auto_capture_ease_type.
Sources: scene/animation/animation_player.cpp559-598 scene/animation/animation_player.h60-63
AnimationMixer per-frame processing flow
Sources: scene/animation/animation_mixer.cpp430-600
AnimationPlayer — Direct PlaybackAnimationPlayer (scene/animation/animation_player.h scene/animation/animation_player.cpp) implements AnimationMixer's virtual blend hooks to produce a sequential playback model: one animation plays at a time, with optional cross-fades when switching.
playback.current — the animation currently playing.playback.blend — list of animations in the process of fading out (each carries a snapshot of PlaybackData plus remaining blend time).playback.assigned — the last animation that was set, persists after stopping.Sources: scene/animation/animation_player.h65-100
| Method | Description |
|---|---|
play(name, custom_blend, custom_speed, from_end) | Start playback from the beginning (or end if from_end) |
play_backwards(name, custom_blend) | Shorthand for play() with custom_speed=-1, from_end=true |
play_section(name, start_time, end_time, ...) | Play only a time-bounded sub-section |
play_section_with_markers(name, start_marker, end_marker, ...) | Use named Animation markers to define the section |
play_with_capture(name, duration, ...) | Capture current property values then play |
pause() | Halts time advancement; position is preserved |
stop(keep_state) | Resets to start (or keeps state) and deactivates |
All play* variants eventually resolve to play_section(), which is the core method that sets up playback.current and creates a Blend entry from the previously playing animation if a blend time is configured.
Sources: scene/animation/animation_player.cpp413-557
When play_section() is called while an animation is already playing, the old animation's PlaybackData is pushed into playback.blend as a Blend entry. On each frame, _blend_playback_data() processes:
1 − Σ(blend_left).blend_left, decrementing blend_left each frame.Cross-fade blend weight computation
Blend times can be configured three ways, in priority order:
custom_blend argument to play() (if ≥ 0).set_blend_time(from, to, seconds) lookup (stored in blend_times: HashMap<BlendKey, double>).default_blend_time fallback.Wildcard entries in blend_times use "*" as the from or to key.
Sources: scene/animation/animation_player.cpp265-302 scene/animation/animation_player.cpp455-505 scene/animation/animation_player.h87-120
PlaybackData holds start_time and end_time fields. When these are set (non-negative), playback is clamped to that window. get_start_time() / get_end_time() fall back to 0 / animation_length when the stored values are out of range.
At runtime on an already-playing animation, use set_section(start, end) or set_section_with_markers(start_marker, end_marker) to redefine the window without restarting. reset_section() clears it.
Sources: scene/animation/animation_player.cpp736-777 scene/animation/animation_player.h73-84
queue(name) adds an animation to playback_queue. When the current animation ends (non-looping), the next queued animation is played automatically via _blend_post_process(), emitting animation_changed(old, new) between each. clear_queue() empties the list.
Sources: scene/animation/animation_player.cpp380-399 scene/animation/animation_player.cpp336-378
animation_set_next(from, to) links two animations so that when from finishes, to is automatically queued. This is stored in animation_next_set: AHashMap<StringName, StringName>. The link is resolved in play_section() and added to playback_queue at play start.
Sources: scene/animation/animation_player.cpp553-556 scene/animation/animation_player.cpp820-830
Setting autoplay to an animation name causes AnimationPlayer to call play(autoplay) in NOTIFICATION_READY when not in editor mode.
Sources: scene/animation/animation_player.cpp148-158
AnimationPlayer Signals| Signal | When emitted |
|---|---|
animation_started(name) | Animation begins playing |
animation_finished(name) | Non-looping animation reaches its end |
animation_changed(old, new) | Queue advances to next animation |
current_animation_changed(name) | current_animation property changes (including to "" on stop) |
Sources: scene/animation/animation_player.cpp336-378 scene/animation/animation_player.cpp526-547
AnimationPlayer _blend_pre_process / _blend_post_process OverridesHow AnimationPlayer hooks into AnimationMixer
Sources: scene/animation/animation_player.cpp304-378 scene/animation/animation_player.cpp160-254
| Structure | File | Role |
|---|---|---|
Animation | scene/resources/animation.h | Resource holding tracks and keys |
AnimationLibrary | scene/resources/animation_library.h | Named group of Animation resources |
AnimationMixer::AnimationLibraryData | animation_mixer.h | Name + library reference stored in animation_libraries |
AnimationMixer::AnimationData | animation_mixer.h | Flat entry in animation_set, includes library name and update pass |
AnimationMixer::PlaybackInfo | animation_mixer.h | Per-instance playback params: time, delta, weight, seeked, track_weights |
AnimationMixer::TrackCache | animation_mixer.h | Resolved node/property target; subtyped per track type |
AnimationPlayer::PlaybackData | animation_player.h | Position + speed + section info for one animation slot |
AnimationPlayer::Blend | animation_player.h | A PlaybackData snapshot with blend_time and blend_left |
AnimationPlayer::Playback | animation_player.h | Entire playback state: current slot + blend list + seeked flags |
AnimationPlayer::BlendKey | animation_player.h | {from, to} pair used as key in blend_times map |
Sources: scene/animation/animation_mixer.h70-220 scene/animation/animation_player.h52-125 scene/resources/animation.h107-236
AnimationMixer Public API Reference| Method | Description |
|---|---|
add_animation_library(name, library) | Register a library; connects change signals |
remove_animation_library(name) | Deregister and disconnect signals |
rename_animation_library(name, new_name) | Rename and update all composite keys |
get_animation_library(name) | Returns Ref<AnimationLibrary> |
has_animation_library(name) | Checks existence |
find_animation_library(animation) | Finds the library containing a given animation ref |
| Method | Description |
|---|---|
get_animation(name) | Returns Ref<Animation> from animation_set |
has_animation(name) | Checks animation_set |
find_animation(animation) | Reverse lookup by Ref<Animation> |
get_animation_list(list) | Populates sorted list of all animation keys |
Sources: scene/animation/animation_mixer.cpp254-424
In editor mode (Engine::get_singleton()->is_editor_hint()), AnimationMixer sets editing = true, which:
active, deterministic, and root_motion_track properties read-only in the inspector.set_process_internal() / set_physics_process_internal() while editing, so the mixer does not auto-advance.AnimatedValuesBackup (a friend class) to snapshot and restore property values for undo/redo in the animation editor.Sources: scene/animation/animation_mixer.h45-47 scene/animation/animation_mixer.cpp137-147 scene/animation/animation_mixer.cpp435-445
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.