CharacterBody2D/3D in Godot 4 — Guida completa

1. Introduzione

Godot 4 ha introdotto grandi cambiamenti nel movimento dei personaggi. I vecchi nodi KinematicBody2D e KinematicBody3D sono stati rinominati in CharacterBody2D e CharacterBody3D, e l'API move_and_slide() è stata completamente riprogettata. Che tu stia migrando da Godot 3 o partendo da zero — questa guida copre tutto ciò che devi sapere.

CharacterBody2D e CharacterBody3D sono physics body pensati per personaggi controllati tramite codice. A differenza di RigidBody, non reagiscono automaticamente alle forze — ne controlli il movimento interamente tramite script. Questo li rende ideali per personaggi giocanti, NPC e tutto ciò che richiede un movimento preciso e deterministico.

2. Cosa è cambiato rispetto a Godot 3

Ecco i cambiamenti più importanti nel movimento dei personaggi tra Godot 3 e Godot 4:

Punto chiave

In Godot 3, move_and_slide() restituiva la velocità risultante. In Godot 4 restituisce un bool (se si è verificata una collisione), e la velocità viene aggiornata direttamente nella proprietà velocity.

3. Controller platformer 2D di base

Questo è il classico controller platformer a scorrimento laterale. Il personaggio può muoversi a sinistra/destra e saltare quando è a terra. È il template che Godot genera quando crei un nuovo 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()

Spiegazione riga per riga

Suggerimento: struttura dei nodi necessaria

Il tuo CharacterBody2D ha bisogno di almeno un nodo figlio CollisionShape2D con una forma assegnata (es. RectangleShape2D o CapsuleShape2D). Senza di essa, move_and_slide() non rileverà alcuna collisione.

4. Controller top-down 2D di base

Per i giochi top-down (RPG, twin-stick shooter ecc.) ti muovi in tutte e quattro le direzioni senza gravità. Il codice è più semplice rispetto a un platformer.

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()

Come funziona

Aggiungere accelerazione e attrito

Per una sensazione più fluida con accelerazione e decelerazione:

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. Controller 3D in terza persona

La variante 3D segue lo stesso schema. La differenza principale è lavorare con Vector3 e usare transform.basis per convertire l'input 2D in movimento nello spazio 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()

Differenze principali rispetto al 2D

Attenzione: get_gravity() richiede Godot 4.4+

Il metodo get_gravity() è stato aggiunto in Godot 4.4. Per le versioni più vecchie usa Vector2(0, ProjectSettings.get_setting("physics/2d/default_gravity")) per il 2D, oppure Vector3(0, -ProjectSettings.get_setting("physics/3d/default_gravity"), 0) per il 3D.

6. Riferimento delle proprietà principali

Sia CharacterBody2D che CharacterBody3D condividono queste importanti proprietà. Regolale nell'Inspector o tramite codice.

Proprietà Tipo Predefinito Descrizione
velocity Vector2 / Vector3 Vector2.ZERO La velocità del personaggio. Impostala prima di chiamare move_and_slide(). Dopo la chiamata viene aggiornata con la velocità risultante.
floor_snap_length float 1.0 Sostituisce move_and_slide_with_snap(). Distanza con cui il personaggio viene agganciato al pavimento. Imposta a 0 per disattivarlo. Utile per pendii e scale.
up_direction Vector2 / Vector3 Vector2.UP Definisce quale direzione è "su". Questo determina cosa viene considerato pavimento, muro o soffitto. Il valore predefinito è (0, -1) in 2D, (0, 1, 0) in 3D.
floor_stop_on_slope bool true Se true, il personaggio non scivola giù per i pendii quando è fermo. Essenziale per i platformer.
floor_max_angle float 0.785 (45°) Angolo massimo di pendenza percorribile in radianti. Le superfici più ripide vengono trattate come muri. Usa deg_to_rad(60) per impostare 60 gradi.
max_slides int 6 Numero massimo di iterazioni di collisione per chiamata a move_and_slide(). Valori più alti sono più precisi ma più lenti.
wall_min_slide_angle float 0.262 (15°) Angolo minimo per lo scivolamento sui muri. Impedisce al personaggio di rimanere bloccato su muri quasi paralleli.
platform_on_leave PlatformOnLeave ADD_VELOCITY Comportamento quando si lascia una piattaforma mobile. ADD_VELOCITY preserva il momento, ADD_UPWARD_VELOCITY aggiunge solo la componente verso l'alto, DO_NOTHING ignora la velocità della piattaforma.
slide_on_ceiling bool true Se true, consente lo scivolamento sui soffitti. Se false, arresta la velocità orizzontale al contatto con il soffitto.

7. Rilevamento delle collisioni dopo move_and_slide()

Dopo aver chiamato move_and_slide(), puoi ispezionare le collisioni verificatesi. È utile per reagire a determinati tipi di collider, riprodurre effetti sonori all'atterraggio o implementare meccaniche di wall-jump.

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

Metodi utili di KinematicCollision

8. Cheat sheet di migrazione

Riferimento rapido per riscrivere il codice di Godot 3 in 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(...)
restituisce velocity
move_and_slide()
la proprietà velocity viene aggiornata direttamente
var gravity = ProjectSettings.get("physics/2d/default_gravity") get_gravity() (4.4+)
move_and_slide(..., up_direction, ...) up_direction = Vector2.UP (impostata come proprietà)
move_and_slide(..., stop_on_slope, ...) floor_stop_on_slope = true (impostata come proprietà)
Il convertitore automatico di Godot

Quando apri un progetto Godot 3 in Godot 4, l'engine propone di convertire il tuo progetto. Rinomina i nodi e tenta di aggiornare gli script, ma non gestisce sempre correttamente le chiamate a move_and_slide(). Probabilmente dovrai correggere manualmente il tuo codice di movimento.

9. Errori comuni

Errore 1: passare argomenti a move_and_slide()

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

Errore 2: dimenticare di impostare velocity prima di move_and_slide()

Sbagliato — velocity non viene mai impostata, quindi nulla si muove
func _physics_process(delta: float) -> void:
    move_and_slide()  # velocity is Vector2.ZERO — nothing happens

Errore 3: usare _process() invece di _physics_process()

move_and_slide() deve essere chiamato in _physics_process(), che gira a una frequenza fissa (60 Hz per impostazione predefinita). Usare _process() lega la fisica al frame rate di rendering e provoca un comportamento incoerente.

Errore 4: non configurare CollisionShape

Un CharacterBody2D/CharacterBody3D senza un figlio CollisionShape attraversa tutto. Godot mostra un'icona di avviso nell'editor se la forma di collisione manca.

Errore 5: sovrascrivere velocity.y con la gravità a ogni frame

Sbagliato — reimposta velocity.y, quindi il salto non funziona mai
# This overwrites any jump velocity!
velocity.y = gravity * delta  # should be +=, not =
Corretto — accumula la gravità
# Gravity accumulates over time
velocity += get_gravity() * delta

Errore 6: applicare la gravità mentre si è a terra

Racchiudi sempre la gravità in if not is_on_floor(). Senza questo controllo, la gravità continua ad accumularsi mentre si è a terra. Quando il personaggio cammina oltre un bordo, precipita a una velocità estrema invece di cadere in modo naturale.

10. Configurare i controller dei personaggi con l'IA

Vuoi che l'IA configuri il tuo controller di personaggio?

Con Godot MCP Pro gli assistenti IA possono creare nodi CharacterBody, configurare le proprietà fisiche, impostare le forme di collisione, scrivere script di movimento, avviare il tuo gioco e testare il movimento — tutto a partire da prompt in linguaggio naturale.

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