CharacterBody2D/3D dans Godot 4 — Guide complet

1. Introduction

Godot 4 a introduit des changements majeurs dans le déplacement des personnages. Les anciens nœuds KinematicBody2D et KinematicBody3D ont été renommés en CharacterBody2D et CharacterBody3D, et l'API move_and_slide() a été entièrement repensée. Que vous migriez depuis Godot 3 ou que vous démarriez de zéro, ce guide couvre tout ce que vous devez savoir.

CharacterBody2D et CharacterBody3D sont des corps physiques conçus pour les personnages contrôlés par du code. Contrairement à RigidBody, ils ne réagissent pas automatiquement aux forces — vous contrôlez entièrement leur déplacement par script. Cela les rend idéaux pour les personnages joueurs, les PNJ et tout ce qui nécessite un déplacement précis et déterministe.

2. Ce qui a changé depuis Godot 3

Voici les changements les plus importants entre Godot 3 et Godot 4 pour le déplacement des personnages :

Point clé

Dans Godot 3, move_and_slide() renvoyait la vélocité résultante. Dans Godot 4, il renvoie un bool (indiquant si une collision s'est produite), et la vélocité est mise à jour sur place via la propriété velocity.

3. Contrôleur de plateforme 2D de base

Voici le contrôleur de plateforme à défilement horizontal standard. Le personnage peut se déplacer à gauche/droite et sauter lorsqu'il est au sol. C'est le modèle que Godot génère lorsque vous créez un nouveau script CharacterBody2D.

GDScript — platformer_controller.gd
extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

func _physics_process(delta: float) -> void:
    # Apply gravity when not on floor
    if not is_on_floor():
        velocity += get_gravity() * delta

    # Jump when on floor and jump pressed
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # Horizontal movement
    var direction := Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)

    move_and_slide()

Décomposition ligne par ligne

Astuce : structure de nœuds requise

Votre CharacterBody2D a besoin d'au moins un nœud enfant CollisionShape2D avec une forme assignée (par exemple, RectangleShape2D ou CapsuleShape2D). Sans cela, move_and_slide() ne détectera aucune collision.

4. Contrôleur vue de dessus 2D de base

Pour les jeux en vue de dessus (RPG, twin-stick shooters, etc.), vous vous déplacez dans les quatre directions sans gravité. Le code est plus simple qu'un contrôleur de plateforme.

GDScript — topdown_controller.gd
extends CharacterBody2D

const SPEED = 200.0

func _physics_process(delta: float) -> void:
    var input_direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = input_direction * SPEED
    move_and_slide()

Comment ça fonctionne

Ajouter de l'accélération et de la friction

Pour une sensation plus fluide avec accélération et décélération :

GDScript — topdown_smooth.gd
extends CharacterBody2D

const SPEED = 200.0
const ACCELERATION = 1200.0
const FRICTION = 1000.0

func _physics_process(delta: float) -> void:
    var input_direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

    if input_direction != Vector2.ZERO:
        velocity = velocity.move_toward(input_direction * SPEED, ACCELERATION * delta)
    else:
        velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)

    move_and_slide()

5. Contrôleur 3D à la troisième personne

La version 3D suit le même modèle. La principale différence est de travailler avec Vector3 et d'utiliser transform.basis pour convertir une entrée 2D en déplacement dans l'espace monde 3D.

GDScript — character_3d.gd
extends CharacterBody3D

const SPEED = 5.0
const JUMP_VELOCITY = 4.5

func _physics_process(delta: float) -> void:
    # Apply gravity
    if not is_on_floor():
        velocity += get_gravity() * delta

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

    # Get input and convert to 3D direction
    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)

    move_and_slide()

Principales différences avec la 2D

Attention : get_gravity() nécessite Godot 4.4+

La méthode get_gravity() a été ajoutée dans Godot 4.4. Pour les versions plus anciennes, utilisez Vector2(0, ProjectSettings.get_setting("physics/2d/default_gravity")) pour la 2D, ou Vector3(0, -ProjectSettings.get_setting("physics/3d/default_gravity"), 0) pour la 3D.

6. Référence des propriétés principales

CharacterBody2D et CharacterBody3D partagent tous deux ces propriétés importantes. Ajustez-les dans l'Inspecteur ou par code.

Propriété Type Par défaut Description
velocity Vector2 / Vector3 Vector2.ZERO La vélocité du personnage. Définissez-la avant d'appeler move_and_slide(). Mise à jour après l'appel avec la vélocité résultante.
floor_snap_length float 1.0 Remplace move_and_slide_with_snap(). Distance d'accrochage du personnage au sol. Réglez sur 0 pour désactiver. Utile pour les pentes et les escaliers.
up_direction Vector2 / Vector3 Vector2.UP Définit quelle direction est « le haut ». Cela détermine ce qui compte comme sol, mur ou plafond. Par défaut (0, -1) en 2D, (0, 1, 0) en 3D.
floor_stop_on_slope bool true Lorsque true, le personnage ne glisse pas le long des pentes à l'arrêt. Essentiel pour les jeux de plateforme.
floor_max_angle float 0.785 (45°) Angle de pente maximal praticable en radians. Les surfaces plus raides sont traitées comme des murs. Utilisez deg_to_rad(60) pour définir 60 degrés.
max_slides int 6 Nombre maximal d'itérations de collision par appel de move_and_slide(). Des valeurs plus élevées sont plus précises mais plus lentes.
wall_min_slide_angle float 0.262 (15°) Angle minimal pour le glissement sur les murs. Empêche le personnage de se coincer sur des murs presque parallèles.
platform_on_leave PlatformOnLeave ADD_VELOCITY Comportement en quittant une plateforme mobile. ADD_VELOCITY conserve l'élan, ADD_UPWARD_VELOCITY n'ajoute que la composante vers le haut, DO_NOTHING ignore la vélocité de la plateforme.
slide_on_ceiling bool true Lorsque true, autorise le glissement sur les plafonds. Lorsque false, arrête la vélocité horizontale au contact du plafond.

7. Détection de collision après move_and_slide()

Après avoir appelé move_and_slide(), vous pouvez inspecter les collisions qui se sont produites. C'est utile pour réagir à des types de colliders spécifiques, jouer des effets sonores à l'atterrissage ou implémenter des mécaniques de saut mural.

GDScript — collision_detection.gd
func _physics_process(delta: float) -> void:
    # ... set velocity here ...
    move_and_slide()

    # Check all collisions from this frame
    for i in get_slide_collision_count():
        var collision := get_slide_collision(i)
        var collider := collision.get_collider()
        print("Collided with: ", collider.name)
        print("Normal: ", collision.get_normal())
        print("Position: ", collision.get_position())

    # Practical example: bounce off enemies
    for i in get_slide_collision_count():
        var collision := get_slide_collision(i)
        if collision.get_collider().is_in_group("enemies"):
            velocity = collision.get_normal() * 300
            break

Méthodes utiles de KinematicCollision

8. Aide-mémoire de migration

Référence rapide pour convertir du code Godot 3 en Godot 4 :

Godot 3 Godot 4
KinematicBody2D CharacterBody2D
KinematicBody3D CharacterBody3D
velocity = move_and_slide(velocity, Vector2.UP) velocity = ...
move_and_slide()
move_and_slide_with_snap(vel, snap, up) floor_snap_length = 4.0
move_and_slide()
var vel = move_and_slide(...)
renvoie la vélocité
move_and_slide()
la propriété velocity est mise à jour sur place
var gravity = ProjectSettings.get("physics/2d/default_gravity") get_gravity() (4.4+)
move_and_slide(..., up_direction, ...) up_direction = Vector2.UP (défini comme propriété)
move_and_slide(..., stop_on_slope, ...) floor_stop_on_slope = true (défini comme propriété)
Le convertisseur automatique de Godot

Lorsque vous ouvrez un projet Godot 3 dans Godot 4, le moteur propose de convertir votre projet. Il renomme les nœuds et tente de mettre à jour les scripts, mais il ne gère pas toujours correctement les appels à move_and_slide(). Vous devrez probablement corriger manuellement votre code de déplacement.

9. Erreurs courantes

Erreur 1 : passer des arguments à move_and_slide()

Incorrect
# ERROR: move_and_slide() takes no arguments in Godot 4
velocity = move_and_slide(velocity, Vector2.UP)
Correct
# Set velocity, then call move_and_slide() with no arguments
velocity.x = direction * SPEED
move_and_slide()

Erreur 2 : oublier de définir velocity avant move_and_slide()

Incorrect — velocity n'est jamais défini, donc rien ne bouge
func _physics_process(delta: float) -> void:
    move_and_slide()  # velocity is Vector2.ZERO — nothing happens

Erreur 3 : utiliser _process() au lieu de _physics_process()

move_and_slide() doit être appelé dans _physics_process(), qui s'exécute à une fréquence fixe (60 Hz par défaut). Utiliser _process() lie la physique à la fréquence d'images du rendu, provoquant un comportement incohérent.

Erreur 4 : ne pas configurer de CollisionShape

Un CharacterBody2D/CharacterBody3D sans nœud enfant CollisionShape traversera tout. Godot affiche une icône d'avertissement dans l'éditeur si la forme de collision est absente.

Erreur 5 : écraser velocity.y avec la gravité à chaque frame

Incorrect — réinitialise velocity.y, donc le saut ne fonctionne jamais
# This overwrites any jump velocity!
velocity.y = gravity * delta  # should be +=, not =
Correct — accumule la gravité
# Gravity accumulates over time
velocity += get_gravity() * delta

Erreur 6 : appliquer la gravité lorsqu'on est au sol

Encadrez toujours la gravité dans if not is_on_floor(). Sans cette vérification, la gravité continue de s'accumuler tant que le personnage est au sol. Lorsque le personnage marche au-delà d'un rebord, il plongera à une vitesse extrême au lieu de tomber naturellement.

10. Configurez des contrôleurs de personnage avec l'IA

Vous voulez que l'IA configure votre contrôleur de personnage ?

Godot MCP Pro permet aux assistants IA de créer des nœuds CharacterBody, de configurer les propriétés physiques, de mettre en place les formes de collision, d'écrire des scripts de déplacement, de lancer votre jeu et de tester le déplacement — le tout à partir d'invites en langage naturel.

add_node setup_physics_body setup_collision set_physics_layers create_script simulate_key play_scene capture_frames
Obtenez Godot MCP Pro — $15