CharacterBody2D/3D no Godot 4 — Guia Completo

1. Introdução

O Godot 4 introduziu grandes mudanças no movimento de personagens. Os antigos nodes KinematicBody2D e KinematicBody3D foram renomeados para CharacterBody2D e CharacterBody3D, e a API do move_and_slide() foi completamente redesenhada. Se você está migrando do Godot 3 ou começando do zero, este guia cobre tudo o que você precisa saber.

CharacterBody2D e CharacterBody3D são corpos físicos projetados para personagens controlados por código. Diferentemente do RigidBody, eles não respondem a forças automaticamente — você controla o movimento deles inteiramente por script. Isso os torna ideais para personagens jogáveis, NPCs e qualquer coisa que precise de movimento preciso e determinístico.

2. O que mudou desde o Godot 3

Estas são as mudanças mais importantes no movimento de personagens entre o Godot 3 e o Godot 4:

Ponto-chave

No Godot 3, move_and_slide() retornava a velocidade resultante. No Godot 4, ele retorna um bool (se ocorreu uma colisão), e a velocidade é atualizada diretamente na propriedade velocity.

3. Controlador básico de plataforma 2D

Este é o controlador padrão de plataforma com rolagem lateral. O personagem pode se mover para a esquerda/direita e pular quando está no chão. Este é o template que o Godot gera quando você cria um novo script de 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()

Explicação linha por linha

Dica: Estrutura de nodes necessária

Seu CharacterBody2D precisa de pelo menos um node filho CollisionShape2D com uma forma atribuída (ex.: RectangleShape2D ou CapsuleShape2D). Sem isso, move_and_slide() não detectará nenhuma colisão.

4. Controlador básico top-down 2D

Para jogos top-down (RPGs, twin-stick shooters, etc.), você se move em todas as quatro direções sem gravidade. O código é mais simples que o de uma plataforma.

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

Como funciona

Adicionando aceleração e atrito

Para uma sensação mais suave com aceleração e desaceleração:

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. Controlador 3D em terceira pessoa

A versão 3D segue o mesmo padrão. A principal diferença é trabalhar com Vector3 e usar transform.basis para converter a entrada 2D em movimento no espaço-mundo 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()

Principais diferenças em relação ao 2D

Aviso: get_gravity() requer Godot 4.4+

O método get_gravity() foi adicionado no Godot 4.4. Para versões mais antigas, use Vector2(0, ProjectSettings.get_setting("physics/2d/default_gravity")) para 2D, ou Vector3(0, -ProjectSettings.get_setting("physics/3d/default_gravity"), 0) para 3D.

6. Referência das principais propriedades

Tanto CharacterBody2D quanto CharacterBody3D compartilham estas propriedades importantes. Ajuste-as no Inspetor ou via código.

Propriedade Tipo Padrão Descrição
velocity Vector2 / Vector3 Vector2.ZERO A velocidade do personagem. Defina isso antes de chamar move_and_slide(). Atualizada após a chamada com a velocidade resultante.
floor_snap_length float 1.0 Substitui move_and_slide_with_snap(). Distância para encaixar o personagem no chão. Defina como 0 para desativar. Útil para rampas e escadas.
up_direction Vector2 / Vector3 Vector2.UP Define qual direção é "para cima". Isso determina o que conta como chão, parede ou teto. O padrão é (0, -1) em 2D e (0, 1, 0) em 3D.
floor_stop_on_slope bool true Quando true, o personagem não desliza pelas rampas ao ficar parado. Essencial para jogos de plataforma.
floor_max_angle float 0.785 (45°) Ângulo máximo de rampa caminhável em radianos. Superfícies mais íngremes que isso são tratadas como paredes. Use deg_to_rad(60) para definir 60 graus.
max_slides int 6 Número máximo de iterações de colisão por chamada de move_and_slide(). Valores maiores são mais precisos, mas mais lentos.
wall_min_slide_angle float 0.262 (15°) Ângulo mínimo para deslizar em paredes. Evita que o personagem fique preso em paredes quase paralelas.
platform_on_leave PlatformOnLeave ADD_VELOCITY Comportamento ao deixar uma plataforma móvel. ADD_VELOCITY preserva o momento, ADD_UPWARD_VELOCITY adiciona apenas a componente para cima, DO_NOTHING ignora a velocidade da plataforma.
slide_on_ceiling bool true Quando true, permite deslizar nos tetos. Quando false, interrompe a velocidade horizontal ao tocar o teto.

7. Detecção de colisão após move_and_slide()

Após chamar move_and_slide(), você pode inspecionar as colisões que ocorreram. Isso é útil para reagir a tipos específicos de colisores, tocar efeitos sonoros ao aterrissar ou implementar mecânicas de pulo em parede.

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étodos úteis de KinematicCollision

8. Guia rápido de migração

Referência rápida para converter código do Godot 3 para o 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(...)
retorna velocity
move_and_slide()
a propriedade velocity é atualizada diretamente
var gravity = ProjectSettings.get("physics/2d/default_gravity") get_gravity() (4.4+)
move_and_slide(..., up_direction, ...) up_direction = Vector2.UP (definido como propriedade)
move_and_slide(..., stop_on_slope, ...) floor_stop_on_slope = true (definido como propriedade)
Conversor automático do Godot

Ao abrir um projeto do Godot 3 no Godot 4, a engine oferece converter o seu projeto. Ela renomeia os nodes e tenta atualizar os scripts, mas nem sempre acerta as chamadas de move_and_slide(). Você provavelmente precisará corrigir manualmente o seu código de movimento.

9. Erros comuns

Erro 1: Passar argumentos para move_and_slide()

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

Erro 2: Esquecer de definir velocity antes de move_and_slide()

Errado — velocity nunca é definida, então nada se move
func _physics_process(delta: float) -> void:
    move_and_slide()  # velocity is Vector2.ZERO — nothing happens

Erro 3: Usar _process() em vez de _physics_process()

move_and_slide() deve ser chamado em _physics_process(), que roda a uma taxa fixa (padrão de 60 Hz). Usar _process() vincula a física à taxa de frames de renderização, causando comportamento inconsistente.

Erro 4: Não configurar o CollisionShape

Um CharacterBody2D/CharacterBody3D sem um filho CollisionShape atravessará tudo. O Godot exibe um ícone de aviso no editor se a forma de colisão estiver ausente.

Erro 5: Sobrescrever velocity.y com gravidade a cada frame

Errado — reseta velocity.y, então o pulo nunca funciona
# This overwrites any jump velocity!
velocity.y = gravity * delta  # should be +=, not =
Correto — acumula a gravidade
# Gravity accumulates over time
velocity += get_gravity() * delta

Erro 6: Aplicar gravidade enquanto está no chão

Sempre envolva a gravidade em if not is_on_floor(). Sem essa verificação, a gravidade continua acumulando enquanto o personagem está no chão. Quando ele sai de uma borda, despenca a uma velocidade extrema em vez de cair naturalmente.

10. Configure controladores de personagem com IA

Quer que a IA configure o seu controlador de personagem?

Com o Godot MCP Pro, os assistentes de IA podem criar nodes CharacterBody, configurar propriedades físicas, definir formas de colisão, escrever scripts de movimento, iniciar o seu jogo e testar o movimento — tudo a partir de prompts em linguagem natural.

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