Make your player roll and animations!
Tags: godot, gamedev, tutorial, beginners
Published: 2023-12-30 23:52:21

In today's article, I'm going to show you how to make your player roll, manage states and basics of animation.

## Creating a new action in the Input Map

Before we start writing our code, let's create a new action into our `Input Map` named **roll**. I've attached the letter `K` on the keyboard, but you can bind any key you prefer.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ocruvg9m4u22piwyo5o.png)

## Adding a new state

Open the `Player.gd` script and lets update our `states` enum, adding the action `ROLL`.

```python
enum states {
   MOVE,
   ROLL
}
```

## Using `_input(event)` to change states

In the previous article I introduced the `_input(event)` method, now, we're going to use it to change the player state based on the player input!

```python
## Called when player input is detected.
## @param event: InputEvent
## @return void
func _input(event):
	if event is InputEventMouseButton or event is InputEventMouseMotion:
		return;

	# Only process input if the player is in the MOVE state.
	if _current_state == states.MOVE:
		# If the player presses the roll button, then the player should roll.
		if event.is_action_pressed("roll"):
			# sets the _current_state to states.ROLL
			_current_state = states.ROLL;
```

First, we're going to check if the player is in the `MOVE` state, this will prevent the player from rolling mid attack, or attack mid rolling.

Then, we check if the player pressed what is mapped to the `roll`, if so, we change the current state to `ROLL`.

## Updating player movement

Now that we changed our state to `ROLL`, we need to tell the script what to do when the player is in this state.

Let's start by creating a `roll` function, like we created with the `move(delta)`. And as we did in the `move(delta)` function, we'll create a new variable, the `_roll_speed`.

```python
@export var _roll_speed: float = 130;
```

Now, we update the `_physics_process(delta)` function to add the call to the roll function.

```python
# delta = time between frames
func _physics_process(delta):
	match _current_state:
		states.MOVE:
			move(delta);
		states.ROLL:
			roll();
```

The editor will throw you an error since we don't have a `roll()` function created, so let's scroll all the way down on our script and create a new function.

```python
func roll():
	velocity = _roll_speed;
	move_and_slide();
```

But wait, we can't simply say the velocity is the `_roll_speed`, we need a vector, just as we used the `input_vector` in our `move(delta)` function.

So let's create a new variable that will receive the input vector and we can use in our roll function.

```python
var _roll_vector: Vector2 = Vector2.RIGHT;
```

This will create a `_roll_vector` variable we can use and will initialise its value to right.

Now, our `roll()` function will look like this:

```python
func roll():
	velocity = _roll_vector * _roll_speed;
	move_and_slide();
```

And we can't forget to update our `move(delta)` function to set our new `_roll_vector`. Let's add the following code before we update our velocity.

```python
# This will be used in the roll() function.
# This will be used to determine which direction the player should roll.
_roll_vector = input_vector;
```
And why we update only when the player moves? Because this will keep the player "facing diretion", so if the player decides to walk to the left, we store this "last facing direction" to our `_roll_vector`, if the player stops, this variable will keep this state, when the player rolls, it will roll to the left.

## Run the player

We're ready to run our game! But notice one thing, if we roll, the player keeps going, and going and we can't stop it! But why this happens?

In the `_input(event)` function we only accept input when the player state is `MOVE`, but we don't have anything telling the script to revert to the `MOVE` state.

To solve this issue, we're going to use animations!

## Creating the animation node.

Let's get back to our player node in Godot and add two new nodes `AnimationPlayer` and `AnimationTree`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lvu2w2fp43a21ewcz8es.png)

Notice the `AnimationTree` have a warning sign next to it, this is because it needs to be told how it should handle animations. Select the `AnimationTree` node and on the right side, in the inspector, and update the `Tree Root` to use `AnimationNodeStateMachine`

The next step, is to assign the `Anim Player` to the animation player we created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3vvzxoesuquqm47u5x0.png)

This will open an `AnimationTree` window on the bottom of Godot, we're going to create a couple of animations (even though they're just the godot icon 😅), and update the animations through our script! 

## Creating new animations

First, select the `Animation` tab in the bottom panel, then, in new panel, click on **Animation** at the top and then select the option **New**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9i6o4qdsme2sdjla7o0.png)

Let's create animations for idle, walk and roll. Each of them having the facing direction, for example, idle_left, idle_right, so on.

You should have something like this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3gbazv9uz5bs99knspb.png)

## Understaing The animation window

Let's start by updating the `roll_right` animation, select it on the drop down and the first thing we're going to do, is to add our sprite to it!
To do this, keep the animation window open, select the `Sprite2D` node in the scene and under **Animation** in the inspector, select frame 0 and press the key icon to the right of it.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4v86cswon23di4asx1i.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qc8elar7m3sbb2ten19y.png)

This will open a new window, just press create.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynhwh1g1pt7vwu2uuwvu.png)

This will add our sprite to the tracks!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bc7xign4kzwy63wypjbw.png)

Cool! we have our first track with our sprite! But before continuing, let's update some options in the window, to make it easier for us to work.

In bottom right of the animation window, change from seconds to FPS.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uge3frb86bjxjm74n75c.png)

Here is where we tell how many frames the animation will have, for the roll animation, lets pretend we have 4 frames, so let's update the value on the left to 4!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dsic7tvqw6e8gi7i7jt.png)

If you press the play button in the animation window, you'll notice that the track will stop on frame 4 (it counts 0,1,2,3), signaling the engine that the animation ended.

## Adding a `Call Method Track`

The **Call Method Track** lets you call a methoid in a script at anypoint of the animation you want! Which is great! because we're going to use this to change the state of our player.

CLick on the **+ Add Track** and select **Call Method Track**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8x2tjm7hgxpt9nrtkfj8.png)

This will open a new window for you to select a node to animate, in this window, select the player. We're selecting the player node becuase we're adding the script there.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbiy2nhjm974m9l9av50.png)

Once you're done, this will create a new track in the Animation window.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2elbqyax0pqj01wyeh9.png)

Let's get back to our `Player.gd` and create a simple function that will set the state back to move, let's call it `on_roll_ended()`.

```python
func on_roll_ended():
	_current_state = states.MOVE;
```

Now, to add your script, make sure the blue vertical bar is at the last frame of your animation (in this case, the end of the third frame beginning of the forth), right click it and press **Add Key**.

In the new window, select the method we just created:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13htawm0paxz1z0745w4.png)

This will tell the Engine that when the roll_right animation ends, it should call the method we assigned.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8g4ywfxlwotf0349gbt.png)

Before we continue, do this for all roll animations 😄.

## The animation Tree

We're almost done, we need to set up the animations in the animation tree so we can use it on our scripts.

Select both animation tree under the player node and in the bottom panel.

You'll see a Start/End blocks, we're going to create a few more, one for idle, one for walk and one for roll. Right click anywhere between Start and End and select the **Add Blend Space 2D** option, once it's created, double click the text and rename it to **Idle**, do the same for walk and roll.

Now, let's link these aniumations together! 
There are a couple of tool in to top left corner of the Animation tree

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skkc87iqf1hbhh2kdm3s.png)

From left to right:
* Select Tool
With this selected, you can click on any node in the animation tree.
* Add Tool
When this is active, clicking anywhere in the animation tree with the left mouse button will open the add pop-up.
* Connect Tool
When Connect Tool is selected, you can link animations together.
* Delete Tool
Deletes the selected node.

Select the Connect Tool and let's start linkin them. To link animations, click on the node you want to link and drag to the next node.

You should have something like this.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fckqg8mysi5np36tkv76.png)

Before we proceed, schange to the select tool and select the lines between nodes, now in the inspector, navigate to **Advance** and change the **Mode** property to **Enabled**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/goldw5ki95dy81hcdgfv.png)

Do this to all connections!
One last step!! (I swear, it's almost at the end) press the pencil icon in the `Roll` node, this will open a window with the details to the Roll (or any animation you pressed) animation.
Let's add our animations we created in the `Animation` window here, and we're ready to use them!

First, change the blend mode to the tree dots here:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w12rh9j6nmyw7irywfsz.png)

Now, select the select tool in the top left corner.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nflfasmcsz72ltzr5rk2.png)

Right click as close as you can to the 0 in the left of the graph > add animation > roll_left. Now, when we set the blend position in our script, it'll update the animation based on the X and Y positions. Do this for the remaining animations!
At the end, you will have something like this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zliw8wmaz5wy8a74ss3.png)

### !! IMPORTANT !!
in Godot, up = -1 and down = 1, that's the reason we add the down animation up and up animation down.

## Updating animations in the script

This is our last step, calling different animations in our script! Open the player script and let's start working on calling these animations!

Open the Player Script, first things first, lets get our nodes in the script, we can do so like this

```python
@onready var animationTree = $AnimationTree;
@onready var animationState = animationTree.get("parameters/playback");
```

There are a couple of new keywords here, let's explore them.

* @onready 
Tells the engine that this variable will be loaded once the player (or the node) is loaded into the scene tree.
* $AnimationTree 
having the `$` sign is a syntax sugar that would be the same as calling `get_node("AnimationTree")`.

### Enable the AnimationTree

In the `_ready()` function, add the following code, this will enable the animation tree once the player is ready.

``` phyton
animationTree.active = true;
```

## Setting up the blend position

In this step, is very important to use the exact names in the animation tree, otherwise you'll get some errors in the run time.

The recipe to set the blend position is:

`animationTree.set("parameters/<Animation_Name>/blend_position", <movement_vector>);`

Let's add the following code in the `_physics_process` function. First, the idle animation, just beneath the `if input_vector == Vector2.ZERO:`

```python
animationTree.set("parameters/Idle/blend_position", input_vector);
```

And for walk and roll animation we can set after the `_roll_vector = input_vector;`

```python
_roll_vector = input_vector;

	animationTree.set("parameters/Walk/blend_position", input_vector);
	animationTree.set("parameters/Roll/blend_position", input_vector);
```

## Calling animations

In this last step, we need to tell the animation state which animation should be playing.

Let's call our animations, `Idle`, `Walk` and `Roll`.

The code is really simple, just use:

```
# For Idle
animationState.travel("Idle");

# For Walk
animationState.travel("Walk");

# For Roll 
animationState.travel("Roll");
```

For the Idle, call it after setting the Idle `blend_position`. For Walk, call it after setting the Walk `blend_position` and for Roll, call it in the `roll()` function.

```python
if input_vector == Vector2.ZERO:
		animationTree.set("parameters/Idle/blend_position", input_vector);
		animationState.travel("Idle");
```

```python
_roll_vector = input_vector;

	animationTree.set("parameters/Walk/blend_position", input_vector);
	animationTree.set("parameters/Roll/blend_position", input_vector);

	animationState.travel("Walk");
```

```
func roll():
	velocity = _roll_vector * _roll_speed;
	animationState.travel("Roll");
	move_and_slide();
```

## CONGRATULATIONS!

Phew, that was a long one, but now you now how powerful the animation can be in Godot! 
Now, when you run the game, once you press the Roll action, your player will roll to the last facing position!

## Thank you!

I hope you're enjoying this series as much as I'm enjoying writing them! 

Thank you for reading it, any problems or questions drop a comment below and I'll get to it!

Thanks again, and I'll see you in the next article!