thedivergentai/godot-animation-tree-mastery
Expert patterns for AnimationTree including StateMachine transitions, BlendSpace2D for directional movement, BlendTree for layered animations, root motion, transition conditions, advance expressions, and state machine sub-states. Use for complex character animation systems with movement blending and state management. Trigger keywords: AnimationTree, AnimationNodeStateMachine, BlendSpace2D, BlendSpace1D, BlendTree, transition_request, blend_position, advance_expression, AnimationNodeAdd2, AnimationNodeBlend2, root_motion.
npx skills add https://github.com/thedivergentai/GD-Agentic-Skills --skill godot-animation-tree-mastery
Expert guidance for Godot's advanced animation blending and state machines.
play() on AnimationPlayer when using AnimationTree — AnimationTree controls the player. Directly calling play() causes conflicts and jitter. Use set("parameters/transition_request") or travel() instead.active = true — AnimationTree is inactive by default. Animations won't play until $AnimationTree.active = true."parameters/StateMachine/transition_request". This ensures compatibility when nodes move in the hierarchy.auto_advance enabled for interactive states — It causes immediate transitions. Use it only for automated sequences like combo chains or death-to-respawn.BlendSpace2D for 1D blending — Blending only speed? Use BlendSpace1D. Blending only two states? Use Blend2. BlendSpace2D is specifically for X+Y directional inputs (strafe).AnimationTree parameters every frame without a guard — Setting parameters via set() every frame regardless of change causes cache invalidation and potential stutter. Check equality first.BlendTrees for simple logic — Every layer adds CPU overhead. If logic can be handled in a StateMachine or a simple script-driven Blend2, do it there.await get_tree().process_frame when updating parameters synchronously — Sometimes the tree needs one frame to reconcile state before the next parameter change takes effect.auto_advance for long cutscenes — If an animation is interrupted, auto_advance can put the character in a broken state. Use Method Tracks to signal state completion instead.Sync groups for animations with wildly different lengths — It forces one animation to play at an extreme speed. Use TimeScale or separate layers for mismatching cycles.LookAtModifier3D.relative default is now false (was true).add_blend_point accepts optional name parameter for labeled points.> MANDATORY: Read the appropriate script before implementing the corresponding pattern.
> Do NOT Load references/advanced-graph-recipes.md unless nested combat graphs, IK look-at, or deep BlendTree layering are in scope.
Guarded AnimationTree parameter writes — prevent redundant set() churn every physics frame.
Programmatic AnimationNodeStateMachinePlayback via travel() / start().
Trigger: multi-machine travel / request queue. Centralizes travel requests across nested playback paths without calling AnimationPlayer.play().
Trigger: locomotion + combat (or air) sub-machines. Nested StateMachine parameter paths and playback handoff.
Trigger: aim/look-at beside the tree. LookAtModifier3D / IK that must not fight bone tracks the tree owns.
AnimationNodeOneShot for recoil, blinks, and hit reactions.
Runtime playback speed for bullet-time or haste multipliers.
Bone filter masks on Add2/Blend2 for upper/lower body separation.
Interactive combat layer mixing inside BlendTree graphs.
CharacterBody motion extraction from AnimationTree root motion.
Sync groups for multi-layer clips that share length (e.g. walk + reload).
Hierarchical StateMachine / nested parameter path architecture.
Visualize current states, travel paths, and blend values at runtime.
Method-track → dispatch_event(name, metadata) signal bridge; decouple VFX/audio from graph code.
Swap tree_root hero vs crowd graph when VisibleOnScreenNotifier3D culls off-screen actors.
| Need | Prefer | Script |
|------|--------|--------|
| Simple clip swap / UI / prop | AnimationPlayer only | Peer godot-animation-player |
| 5+ gameplay states, travel | StateMachine root | statemachine_travel_code.gd, tree_travel_manager.gd |
| Speed only blend | BlendSpace1D | Guarded writes via sync_parameter_manager.gd |
| Strafe / aim X+Y | BlendSpace2D | Same + blend_position |
| Upper-body overlay / combat layer | BlendTree Add2/Blend2/OneShot | blendtree_logic_mixing.gd, reactive_oneshot_vfx.gd |
| Nested combat/air under locomotion | Nested SM | MANDATORY nested_state_machine.gd |
| Look-at / IK | Modifier beside tree | MANDATORY skeleton_ik_lookat.gd |
| Deep graph recipes | references/ | Do NOT Load unless needed → advanced-graph-recipes.md |
Core Concepts (compact): AnimationTree owns an AnimationPlayer via anim_player; root is StateMachine / BlendTree / BlendSpace; parameters use relative "parameters/..." paths; set active = true once in _ready.
@onready var anim_tree: AnimationTree = $AnimationTree
@onready var playback: AnimationNodeStateMachinePlayback = anim_tree.get("parameters/StateMachine/playback")
func _ready() -> void:
anim_tree.active = true
Do not paste full StateMachine/BlendSpace editor walkthroughs — author graphs in the AnimationTree editor, then drive them with the scripts above.
travel() is explicit pathing. Use conditions for damage/death events; travel for locomotion intent.set() invalidates tree cache every frame. Route writes through sync_parameter_manager.gd.| Topic | Reference / script |
|-------|-------------------|
| StateMachine / BlendSpace editor recipes | statemachine-and-blendspace.md |
| Nested combat / IK / root motion | advanced-graph-recipes.md |
> Progressive disclosure: open Official Documentation links only when researching a specific API;
> load Related Skills when routing work to a peer domain — do not preload the whole lattice.
play() yourself.active, tree_root, anim_player, root-motion getters, and the parameters/* path contract used throughout this skill.travel().travel(), start(), get_current_node(), and travel-path inspection for code-driven state changes.auto_advance, Sync, xfade, and priority rules that prevent sticky or immediate unwanted transitions.blend_position (use BlendSpace1D when only speed is needed).relative default change called out above.blend_position, advance conditions, and travel targets each physics frame.active culling.Take thedivergentai/godot-animation-tree-mastery from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.