Using AnimationTree

Introduction

With AnimationPlayer, Godot has one of the most flexible animation systems that you can find in any game engine. The ability to animate almost any property in any node or resource, as well as having dedicated transform, bezier, function calling, audio and sub-animation tracks, is pretty much unique.

However, the support for blending those animations via AnimationPlayer is relatively limited, as only a fixed cross-fade transition time can be set.

AnimationTree is a new node introduced in Godot 3.1 to deal with advanced transitions. It supersedes the ancient AnimationTreePlayer, while adding a huge amount of features and flexibility.

Creating an AnimationTree

Before starting, it must be made clear that an AnimationTree node does not contain its own animations. Instead, it uses animations contained in an AnimationPlayer node. This way, you can edit your animations (or import them from a 3D scene) as usual and then use this extra node to control the playback.

The most common way to use AnimationTree is in a 3D scene. When importing your scenes from a 3D exchange format, they will usually come with animations built-in (either multiple ones or split from a large one on import). At the end, the imported Godot scene will contain the animations in a AnimationPlayer node.

As you rarely use imported scenes directly in Godot (they are either instantiated or inherited from), you can place the AnimationTree node in your new scene which contains the imported one. Afterwards, point the AnimationTree node to the AnimationPlayer that was created in the imported scene.

This is how it's done in the Third Person Shooter demo, for reference:

../../_images/animtree1.png

A new scene was created for the player with a CharacterBody3D as root. Inside this scene, the original .dae (Collada) file was instantiated and an AnimationTree node was created.

Creating a tree

There are three main types of nodes that can be used in AnimationTree:

  1. Animation nodes, which reference an animation from the linked AnimationPlayer.

  2. Animation Root nodes, which are used to blend sub-nodes.

  3. Animation Blend nodes, which are used within AnimationNodeBlendTree as single-graph blending via multiple input ports.

To set a root node in AnimationTree, a few types are available:

../../_images/animtree2.png
  • AnimationNodeAnimation: Selects an animation from the list and plays it. This is the simplest root node, and generally not used directly as root.

  • AnimationNodeBlendTree: Contains many blend type nodes, such as mix, blend2, blend3, one shot, etc. This is one of the most commonly used roots.

  • AnimationNodeStateMachine: Contains multiple root nodes as children in a graph. Each node is used as a state, and provides multiple functions to alternate between states.

  • AnimationNodeBlendSpace2D: Allows placing root nodes in a 2D blend space. Control the blend position in 2D to mix between multiple animations.

  • AnimationNodeBlendSpace1D: Simplified version of the above (1D).

Blend tree

An AnimationNodeBlendTree can contain both root and regular nodes used for blending. Nodes are added to the graph from a menu:

../../_images/animtree3.webp

All blend trees contain an Output node by default, and something has to be connected to it in order for animations to play.

The easiest way to test this functionality is to connect an Animation node to it directly:

../../_images/animtree4.png

This will simply play back the animation. Make sure that the AnimationTree is active for something to actually happen.

Following is a short description of available nodes:

Blend2 / Blend3

These nodes will blend between two or three inputs by a user-specified blend value:

../../_images/animtree5.gif

For more complex blending, it is advised to use blend spaces instead.

Blending can also use filters, i.e. you can control individually which tracks go through the blend function. This is very useful for layering animations on top of each other.

../../_images/animtree6.png

OneShot

This node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters.

../../_images/animtree6b.gif

After setting the request and changing the animation playback, the one-shot node automatically clears the request on the next process frame by setting its request value to AnimationNodeOneShot.ONE_SHOT_REQUEST_NONE.

# Play child animation connected to "shot" port.
animation_tree.set("parameters/OneShot/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/request"] = AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE

# Abort child animation connected to "shot" port.
animation_tree.set("parameters/OneShot/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_ABORT)
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/request"] = AnimationNodeOneShot.ONE_SHOT_REQUEST_ABORT

# Get current state (read-only).
animation_tree.get("parameters/OneShot/active"))
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/active"]

TimeSeek

This node can be used to cause a seek command to happen to any sub-children of the animation graph. Use this node type to play an Animation from the start or a certain playback position inside the AnimationNodeBlendTree.

After setting the time and changing the animation playback, the seek node automatically goes into sleep mode on the next process frame by setting its seek_request value to -1.0.

# Play child animation from the start.
animation_tree.set("parameters/TimeSeek/seek_request", 0.0)
# Alternative syntax (same result as above).
animation_tree["parameters/TimeSeek/seek_request"] = 0.0

# Play child animation from 12 second timestamp.
animation_tree.set("parameters/TimeSeek/seek_request", 12.0)
# Alternative syntax (same result as above).
animation_tree["parameters/TimeSeek/seek_request"] = 12.0