A lot has changed in Godot 4. From rendering to the GD script. And this post is for those who are looking for a Godot 4 2D top-down character controller.

We can create a 2D character controller using the new Godot 4 CharacterBody2D node. It is a 2D physics body node specialized for the characters moved by script.

We will start by creating a separate scene for our player character. This step is optional but follow along for the sake of this tutorial.

Create a new scene

Change your viewport to 2D mode and click the plus icon located on top of your viewport to create a new scene.

add new scene

Or you can right-click in the File System and then click on create a new scene.

Add a root node to the scene

Now that we have our empty scene we have to add a root node to it. We will add the CharacterBody2D node as the root node of our player scene. To add a root node click the plus icon on the top left corner of the scene tab.

add node button

This will open a Create New Node window. Here search for the name of the node that you want to add. We are searching for the CharacterBody2D node so will type it in the search bar, Once you find the node select it and click the create button or double-click the node to create it.

search node

Let’s rename it by right-clicking on the node and selecting rename. I will name it “PlayerCharacter”. We can also add a sprite to our player character by adding a Sprite2D node as a child.

Add the CollisionShape2D node to the PlayerBody2D

As you have noticed that there is a yellow triangle on the PlayerBody2D node. This is because the PlayerBody2D node requires a CollisionShape2D node as a child.

Right-click on the PlayerBody2D node and click on the add a child node Now search for the CollisionShape2D and hit create.

As you can see CollisionShape2D node is also showing as the yellow triangle. This means it needs a shape.

To add a shape

  1. select the CollisionShape2D node
  2. in the inspector and click the down arrow on the Shape property
  3. A list of possible shapes to add should open
  4. Select the shape that fits your character

I will select the rectangle shape 2D.

add collision shape to player character

Add Script to the node

Here’s how to add the script to node

  1. Right-click on node
  2. Now click the Attach Script option on the right-click menu
  3. An Attach Node Script window should open
  4. In this window select the path and name of the script
  5. And click the create button

attach script to node

We will name our script “player_character” and hit the create button.

name your script

Create Input Map

Now we need to create an Input map for our game. we will use this Input Map to get input for our game from many input devices. To make an input map click the Project option in the top left menu and then Project Settings

project settings

Once the Project Settings window popup

  1. click on the Input Map tab
  2. Add a name for your new action and hit enter
  3. Now in the actions list click the plus icon on your action
  4. There you can map your input keys

input-map

Write a 2D top-down player controller in GDScript

Once we set up the essential nodes and Input Map we can start writing the player controller script.

Add the below code to the player controller script.

extends CharacterBody2D

In the above code, we are inheriting from the CharacterBody2D class to use its methods.

Now let’s add some logic to it

extends CharacterBody2D
@export var player_speed = 100

func _process(delta):
    var direction = Vector2(
   	 Input.get_action_strength("right") - Input.get_action_strength("left"),
   	 Input.get_action_strength("down") - Input.get_action_strength("up")
    )

    direction = direction.normalized()

    velocity = direction * player_speed

    move_and_slide()

Wow! That’s a lot of code. Let’s understand it line by line. First, we are exporting the player_speed variable so that we can edit it in the inspector.

Notice that the export syntax is different in Godot 4 from Godot 3

The _process(delta) method

The _process(delta) method is from the Godot engine. It is called every frame. We are using it so that we can update the player’s position in every frame. Here delta is the amount of time elapsed during one frame.

Input direction

Next, we are taking the player input as Vector2 and storing it in the direction variable.

We use the Input.get_action_strength() method to get the input from the action map.

For the x-axis, we are subtracting the left direction from the right direction. This way if the player presses left then the value will be -1 and player presses the right then the value will be 1

We are doing the same on the y-axis. The only difference is that we are subtracting the up direction from the down direction. Remember Godot’s y-axis is upside down.

In the next line, we are normalizing the direction so the magnitude remains at 1.

Now we are assigning the velocity by multiplying the direction vector by the player_speed. velocity is part of the CharacterBody2D class that we have extended.

The move_and_slide() method

Next up we are calling the move_and_slide() method of the CharacterBody2D class. As you have already noticed that it does not need any arguments.

This is different from Godot 3 which requires arguments.

In Godot 4 the move_and_slide() method uses the velocity parameter internally.

There you have it. With that said this article ends here.

If you find this article helpful then please share it.

Sharing is caring.