Utilizing the CharacterBody 2D and 3D nodes in Godot 4

Utilizing the CharacterBody 2D and 3D nodes in Godot 4


3 min read

Working with the node formerly known as KinematicBody

The node formerly known as KinematicBody

When making 3D games in Godot 3 it was very common to base the player character on the KinematicBody node as they are a special type of Physics Body ment to be user controlled. The equivalent for 2D games was the KinematicBody2D.

One goal in Godot 4's development was to simplify the node tree and make the naming more consistent. To that effort, KinematicBody was renamed to CharacterBody3D and KinematicBody2D was renamed to CharacterBody2D. This was a common change for nodes with 2D/3D counterparts. No longer is the lack of a suffix equated to implied 3D, the 3D is now explicitly appended. The documentation lists some of these renamings.

KinematicBody and KinematicBody2D on the left with arrow pointing right to their new names; CharacterBody3D and CharacterBody2D

This class consistency renaming is also apparent if you compare the the class hierarchies of KinematicBody and CharacterBody3D.

New functionality in CharacterBody

For the remainder of this article we'll focus on CharacterBody3D specifically but much/most of this is relevant to CharacterBody2D also.

Few more methods

If we compare the methods exposed for KinematicBody vs CharacterBody3D we see some expansion. For instance in addition to is_on_floor, we have is_on_floor_only. The former returns true if the body collided only with the floor on the last call of move_and_slide.

Changes with move_and_... methods

In Godot 3 methods such as move_and_slide had gotten a bit unruly with regards to their method signatures.

# KinematicBody

move_and_slide ( Vector3 linear_velocity, Vector3 up_direction=Vector3( 0, 0, 0 ), bool stop_on_slope=false, int max_slides=4, float floor_max_angle=0.785398, bool infinite_inertia=true )

With this function centric approach, as more features were added to the engine for which move and slide would need to be informed of, we would need to add yet another param to the method with a default value to protect backwards compatibility. This doesn't scale well and makes the method overly complex.

In Godot 4, in a more object oriented design, these parameters have been moved out to first class properties of the CharacterBody3D class.

So now in CharacterBody3D we manipulate these properties on the object prior to calling move_and_slide which now has zero parameters and simply returns true if the body collided, otherwise, returns false.

We can see this in play in the new Godot provided CharacterBody3D script template for basic movement.

extends CharacterBody3D

const SPEED = 5.0 const JUMP_VELOCITY = 4.5

# Get the gravity from the project settings to be synced with RigidBody nodes. var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")

func _physics_process(delta: float) -> void: # Add the gravity. if not is_on_floor(): velocity.y -= gravity * delta

# Handle Jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = JUMP_VELOCITY

# Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() if direction: velocity.x = direction.x * SPEED velocity.z = direction.z * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) velocity.z = move_toward(velocity.z, 0, SPEED)

# Note, now zero parameters for move_and_slide move_and_slide()

Wrap up

As you can see core classes such as the formerly named Kinematic Bodies have been unified and simplified in Godot 4 in the form of the Character Body classes. This is only one small piece of the improvements of Godot 4 and you can find a few more details in the docs here.

I hope you found this useful and I encourage you to subscribe to this newsletter and the ExploreGameDev YouTube channel to get notified of new posts here and tutorial videos on YouTube.