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.
What this skill does
# AnimationTree Mastery
Expert guidance for Godot's advanced animation blending and state machines.
## NEVER Do
- **NEVER call `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 [12].
- **NEVER forget to set `active = true`** — AnimationTree is inactive by default. Animations won't play until `$AnimationTree.active = true` [13].
- **NEVER use absolute paths for parameter access** — Use relative paths like `"parameters/StateMachine/transition_request"`. This ensures compatibility when nodes move in the hierarchy [14].
- **NEVER leave `auto_advance` enabled for interactive states** — It causes immediate transitions. Use it only for automated sequences like combo chains or death-to-respawn [15, 121].
- **NEVER use `BlendSpace2D` for 1D blending** — Blending only speed? Use `BlendSpace1D`. Blending only two states? Use `Blend2`. `BlendSpace2D` is specifically for X+Y directional inputs (strafe) [16, 142].
- **NEVER update `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.
- **NEVER use deep, nested `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.
- **NEVER forget to handle `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.
- **NEVER rely on `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.
- **NEVER use `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.
---
## Available Scripts
> **MANDATORY**: Read the appropriate script before implementing the corresponding pattern.
### [sync_parameter_manager.gd](scripts/sync_parameter_manager.gd)
Expert management of `AnimationTree` parameters with guards to prevent redundant updates and GPU cache churn.
### [reactive_oneshot_vfx.gd](scripts/reactive_oneshot_vfx.gd)
Using `AnimationNodeOneShot` for high-priority reactive animations like recoil, blinks, and hit reactions.
### [dynamic_timescale_control.gd](scripts/dynamic_timescale_control.gd)
Runtime manipulation of playback speed for bullet-time effects or movement haste multipliers.
### [advanced_transition_masking.gd](scripts/advanced_transition_masking.gd)
Procedural bone filtering (masking) for nodes like `Add2` to separate upper/lower body animations.
### [statemachine_travel_code.gd](scripts/statemachine_travel_code.gd)
Programmatic control of `AnimationNodeStateMachinePlayback` using `travel()` and `start()`.
### [blendtree_logic_mixing.gd](scripts/blendtree_logic_mixing.gd)
Complex mixing patterns for `BlendTree` nodes to create interactive combat layers.
### [root_motion_animtree_sync.gd](scripts/root_motion_animtree_sync.gd)
Expert 3D CharacterBody motion extraction optimized specifically for `AnimationTree` nodes.
### [sync_group_layering.gd](scripts/sync_group_layering.gd)
Using Sync Groups to keep multi-layered animations (e.g. walk and reload) perfectly aligned.
### [nested_tree_architecture.gd](scripts/nested_tree_architecture.gd)
Pattern for managing hierarchical State Machines and nested node parameter paths.
### [runtime_tree_debugging.gd](scripts/runtime_tree_debugging.gd)
Interactive tool for visualizing current states, transition paths, and blend values in real-time.
---
## Core Concepts
### AnimationTree Structure
```
AnimationTree (node)
├─ Root (assigned in editor)
│ ├─ StateMachine (common)
│ ├─ BlendTree (layering)
│ └─ BlendSpace (directional)
└─ anim_player: NodePath → points to AnimationPlayer
```
### Parameter Access
```gdscript
# Set parameters using string paths
$AnimationTree.set("parameters/StateMachine/transition_request", "run")
$AnimationTree.set("parameters/Movement/blend_position", Vector2(1, 0))
# Get current state
var current_state = $AnimationTree.get("parameters/StateMachine/current_state")
```
---
## StateMachine Pattern
### Basic Setup
```gdscript
# Scene structure:
# CharacterBody2D
# ├─ AnimationPlayer (has: idle, walk, run, jump, land)
# └─ AnimationTree
# └─ Root: AnimationNodeStateMachine
# StateMachine nodes (created in AnimationTree editor):
# - Idle (AnimationNode referencing "idle")
# - Walk (AnimationNode referencing "walk")
# - Run (AnimationNode referencing "run")
# - Jump (AnimationNode referencing "jump")
# - Land (AnimationNode referencing "land")
@onready var anim_tree: AnimationTree = $AnimationTree
@onready var state_machine: AnimationNodeStateMachinePlayback = anim_tree.get("parameters/StateMachine/playback")
func _ready() -> void:
anim_tree.active = true
func _physics_process(delta: float) -> void:
var velocity := get_velocity()
# State transitions based on gameplay
if is_on_floor():
if velocity.length() < 10:
state_machine.travel("Idle")
elif velocity.length() < 200:
state_machine.travel("Walk")
else:
state_machine.travel("Run")
else:
if velocity.y < 0: # Rising
state_machine.travel("Jump")
else: # Falling
state_machine.travel("Land")
```
### Transition Conditions (Advance Expressions)
```gdscript
# In AnimationTree editor:
# Add transition from Idle → Walk
# Set "Advance Condition" to "is_walking"
# In code:
anim_tree.set("parameters/conditions/is_walking", true)
# Transition fires automatically when condition becomes true
# Useful for event-driven transitions (hurt, dead, etc.)
# Example: Damage transition
anim_tree.set("parameters/conditions/is_damaged", false) # Reset each frame
func take_damage() -> void:
anim_tree.set("parameters/conditions/is_damaged", true)
# Transition to "Hurt" state fires immediately
```
### Auto-Advance (Combo Chains)
```gdscript
# In AnimationTree editor:
# Transition from Attack1 → Attack2
# Enable "Auto Advance" (no condition needed)
# Code:
state_machine.travel("Attack1")
# Attack1 animation plays
# When Attack1 finishes, automatically transitions to Attack2
# When Attack2 finishes, transitions to Idle (next auto-advance)
# Useful for:
# - Attack combos
# - Death → Respawn
# - Cutscene sequences
```
---
## BlendSpace2D (Directional Movement)
### 8-Way Movement
```gdscript
# Create BlendSpace2D in AnimationTree editor:
# - Add animations at positions:
# - (0, -1): walk_up
# - (0, 1): walk_down
# - (-1, 0): walk_left
# - (1, 0): walk_right
# - (-1, -1): walk_up_left
# - (1, -1): walk_up_right
# - (-1, 1): walk_down_left
# - (1, 1): walk_down_right
# - (0, 0): idle (center)
# In code:
func _physics_process(delta: float) -> void:
var input := Input.get_vector("left", "right", "up", "down")
# Set blend position (AnimationTree interpolates between animations)
anim_tree.set("parameters/Movement/blend_position", input)
# BlendSpace2D automatically blends animations based on input
# input = (0.5, -0.5) → blends walk_right and walk_up
```
### BlendSpace1D (Speed Blending)
```gdscript
# For walk → run transitions
# Create BlendSpace1D:
# - Position 0.0: walk
# - Position 1.0: run
func _physics_process(delta: float) -> void:
var speed := velocity.length()
var max_speed := 400.0
var blend_value := clamp(speed / max_speed, 0.0, 1.0)
anim_tree.set("parameters/SpeedBlend/blend_position", blend_value)
# Smoothly blends from walk → run as speed increases
```
---
## BlendTree (Layered Animations)
### Add Upper Body AnimRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.