Animation State Machine

In the previous article on Character Animation, we saw a simple example of transitioning to and from another animation. The animations state machine is able to do much more than that to handle various use cases which will be explained in this article.

State graph

The animation state machine can be thought of as a directed graph linking different states with a predicate function that determines if it is possible to transition to the other state. Some transitions may be bi-directional, meaning that you can transition back and forth if the predicate is true or false. However, in some cases it may be more appropriate to not be able to go back in which case you can have uni-directional transitions.

Transitions

Transitions are defined using functions on the animation states to link to other states.

  • transitionsTo(state, predicate) - If the predicate returns true, the state machine will transition to the given state.

  • transitionsBetween(state, predicate) - Similar to transitionsTo but also defines the opposite transition rule to allow for going back and forth between the states.

  • transitionsOnComplete(state, predicate?) - For states that naturally ends such as performing a jump that should transition to a falling state after the jump animation finishes. The predicate is optional but can be useful when you have multiple possible states that you can transition to and you need to select one for which the predicate is true.

Child states

A child state represents a more specific version of another state. For example, you may have a walking state and then different states for strafing left and right that are children of the walking state. If you then want to have a possible transition to a jump state, you can define the transition from the root walking state to the jump state without having to also define transitions from all the different versions of walking states.

For a character with a complex movement system and lots of different animations, the amount of states can be large and the amount of possible transitions between all these states can becomes hard to manage. In these cases child states may help.

In the following example we see how child states can be created using the createChild function. We use some variables in the example to represent state such as what direction the player is moving in and whether the character is falling or not. We can define a transition from any walking state by using the parent walk state and using the transitionsBetween function to the fall state.

let movementDirection = 0
let falling = false

const walk = new AnimationState(walkClip)
const walkLeft = walk.createChild(walkLeftClip, () => movementDirection < 0)
const walkRight = walk.createChild(walkRightClip, () => movementDirection > 0)

const fall = new AnimationState(fallClip)
walk.transitionsBetween(fall, () => falling)

For a more complex example, see the code for the third person starter project.

Last updated