# 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.

```typescript
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.

{% embed url="<https://github.com/hologyengine/starter-third-person-shooter/blob/main/src/actors/character-actor.ts#L119-L149>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hology.app/gameplay/animation/animation-state-machine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
