$npx -y skills add thedivergentai/GD-Agentic-Skills --skill godot-animation-playerExpert patterns for AnimationPlayer including track types (Value, Method, Audio, Bezier), root motion extraction, animation callbacks, procedural animation generation, call mode optimization, and RESET tracks. Use for timeline-based animations, cutscenes, or UI transitions. Trigg
| 1 | # AnimationPlayer |
| 2 | |
| 3 | Expert guidance for Godot's timeline-based keyframe animation system. |
| 4 | |
| 5 | ## NEVER Do |
| 6 | |
| 7 | - **NEVER forget RESET tracks** — Without a RESET track, animated properties don't restore to initial values when changing scenes. Create RESET animation with all default states [12]. |
| 8 | - **NEVER use `Animation.CALL_MODE_CONTINUOUS` for function calls** — This calls the method EVERY frame during the keyframe. Use `CALL_MODE_DISCRETE` (calls once) to avoid logic spam [13, 77]. |
| 9 | - **NEVER animate resource properties directly** — Animating `material.albedo_color` creates embedded resources that bloat file size. Store the material in a variable or use `instance uniform` instead [14]. |
| 10 | - **NEVER use `animation_finished` for looping animations** — This signal doesn't fire for looped animations. Use `animation_looped` or check `current_animation` in `_process()`. |
| 11 | - **NEVER hardcode animation names as strings across large codebases** — Use constants or enums. Typos cause silent failures. |
| 12 | - **NEVER use `seek()` without `update=true` for same-frame logic** — If you need properties to update immediately (e.g., for physics checks), you MUST set the `update` parameter to `true`. |
| 13 | - **NEVER leave unnecessary AnimationPlayers `active`** — If an entity is off-screen and its animation is purely visual (no logic tracks), set `active = false` to save significant CPU/GPU processing [317]. |
| 14 | - **NEVER change `AnimationLibrary` content while it is playing** — This causes immediate crashes or undefined transform states. Stop the player or wait for the `finished` signal before swapping libraries. |
| 15 | - **NEVER rely on `speed_scale` for long-term synchronization** — For multiplayer or rhythm games, use `seek()` with a global time reference to prevent frame-drift. |
| 16 | |
| 17 | --- |
| 18 | |
| 19 | ## Godot 4.7: Animation |
| 20 | |
| 21 | - Animation editor tracks can be **collapsed** for dense timelines. |
| 22 | - `Animation.length` metadata is **double** precision (was float). |
| 23 | |
| 24 | ## Available Scripts |
| 25 | |
| 26 | > **MANDATORY**: Read the appropriate script before implementing the corresponding pattern. |
| 27 | |
| 28 | ### [method_track_logic.gd](scripts/method_track_logic.gd) |
| 29 | Expert logic triggers using `CALL_MODE_DISCRETE` for high-precision hitbox and state management. |
| 30 | |
| 31 | ### [runtime_anim_lib_swapper.gd](scripts/runtime_anim_lib_swapper.gd) |
| 32 | Managing multiple `AnimationLibrary` resources (Stances, Weapons) on a single `AnimationPlayer`. |
| 33 | |
| 34 | ### [dynamic_shader_animation.gd](scripts/dynamic_shader_animation.gd) |
| 35 | Animating shader uniforms (e.g., dissolve, glow) in sync with timeline keyframes. |
| 36 | |
| 37 | ### [procedural_track_modifier.gd](scripts/procedural_track_modifier.gd) |
| 38 | Runtime modification of existing tracks (e.g., jump height tweaking) without creating new Animation resources. |
| 39 | |
| 40 | ### [reset_track_orchestrator.gd](scripts/reset_track_orchestrator.gd) |
| 41 | Pattern for forced, immediate state resets across complex multi-track node setups. |
| 42 | |
| 43 | ### [bezier_curve_extraction.gd](scripts/bezier_curve_extraction.gd) |
| 44 | Extracting numeric data from Bezier tracks at runtime to drive procedural VFX or physics. |
| 45 | |
| 46 | ### [active_animation_culler.gd](scripts/active_animation_culler.gd) |
| 47 | Performance optimization: using `VisibleOnScreenNotifier` to disable `AnimationPlayer.active`. |
| 48 | |
| 49 | ### [root_motion_physics_sync.gd](scripts/root_motion_physics_sync.gd) |
| 50 | Expert 3D CharacterBody motion extraction using `get_root_motion_position`. |
| 51 | |
| 52 | ### [character_part_swapper_tracks.gd](scripts/character_part_swapper_tracks.gd) |
| 53 | Character customization (equipment/slots) managed entirely through Animation timeline tracks. |
| 54 | |
| 55 | ### [precise_audio_sync.gd](scripts/precise_audio_sync.gd) |
| 56 | Perfectly timed SFX using `TYPE_AUDIO` tracks with volume, pitch, and start-offset control. |
| 57 | |
| 58 | --- |
| 59 | |
| 60 | ## Track Types Deep Dive |
| 61 | |
| 62 | ### Value Tracks (Property Animation) |
| 63 | |
| 64 | ```gdscript |
| 65 | # Animate ANY property: position, color, volume, custom variables |
| 66 | var anim := Animation.new() |
| 67 | anim.length = 2.0 |
| 68 | |
| 69 | # Position track |
| 70 | var pos_track := anim.add_track(Animation.TYPE_VALUE) |
| 71 | anim.track_set_path(pos_track, ".:position") |
| 72 | anim.track_insert_key(pos_track, 0.0, Vector2(0, 0)) |
| 73 | anim.track_insert_key(pos_track, 1.0, Vector2(100, 0)) |
| 74 | anim.track_set_interpolation_type(pos_track, Animation.INTERPOLATION_CUBIC) |
| 75 | |
| 76 | # Color track (modulate) |
| 77 | var color_track := anim.add_track(Animation.TYPE_VALUE) |
| 78 | anim.track_set_path(color_track, "Sprite2D:modulate") |
| 79 | anim.track_insert_key(color_track, 0.0, Color.WHITE) |
| 80 | anim.track_insert_key(color_track, 2.0, Color.TRANSPARENT) |
| 81 | |
| 82 | $AnimationPlayer.add_animation("fade_move", anim) |
| 83 | $AnimationPlayer.play("fade_move") |
| 84 | ``` |
| 85 | |
| 86 | ### Method Trac |