CharacterBody2D/3D w Godot 4 — Kompletny poradnik

1. Wprowadzenie

Godot 4 wprowadził poważne zmiany w ruchu postaci. Stare węzły KinematicBody2D i KinematicBody3D zostały przemianowane na CharacterBody2D i CharacterBody3D, a API move_and_slide() zostało całkowicie przeprojektowane. Niezależnie od tego, czy migrujesz z Godot 3, czy zaczynasz od zera, ten poradnik obejmuje wszystko, co musisz wiedzieć.

CharacterBody2D i CharacterBody3D to ciała fizyczne przeznaczone dla postaci kontrolowanych przez kod. W przeciwieństwie do RigidBody nie reagują automatycznie na siły — ich ruchem sterujesz w całości za pomocą skryptu. Sprawia to, że są idealne dla postaci gracza, NPC i wszystkiego, co wymaga precyzyjnego, deterministycznego ruchu.

2. Co się zmieniło względem Godot 3

Oto najważniejsze zmiany w ruchu postaci między Godot 3 a Godot 4:

Kluczowa obserwacja

W Godot 3 move_and_slide() zwracało wynikową prędkość. W Godot 4 zwraca bool (czy wystąpiła kolizja), a prędkość jest aktualizowana w miejscu na właściwości velocity.

3. Podstawowy kontroler platformówki 2D

To standardowy kontroler platformówki z przewijaniem bocznym. Postać może poruszać się w lewo/prawo i skakać, gdy jest na ziemi. To szablon, który Godot generuje, gdy tworzysz nowy skrypt 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()

Analiza wiersz po wierszu

Wskazówka: Wymagana struktura węzłów

Twój CharacterBody2D potrzebuje co najmniej jednego węzła potomnego CollisionShape2D z przypisanym kształtem (np. RectangleShape2D lub CapsuleShape2D). Bez niego move_and_slide() nie wykryje żadnych kolizji.

4. Podstawowy kontroler top-down 2D

W grach z widokiem z góry (RPG, twin-stick shootery itp.) poruszasz się we wszystkich czterech kierunkach bez grawitacji. Kod jest prostszy niż w platformówce.

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

Jak to działa

Dodawanie przyspieszenia i tarcia

Aby uzyskać płynniejsze wrażenie z przyspieszaniem i zwalnianiem:

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. Kontroler trzecioosobowy 3D

Wersja 3D podąża za tym samym wzorcem. Główna różnica polega na pracy z Vector3 i użyciu transform.basis do przekształcenia wejścia 2D w ruch w przestrzeni świata 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()

Kluczowe różnice względem 2D

Ostrzeżenie: get_gravity() wymaga Godot 4.4+

Metoda get_gravity() została dodana w Godot 4.4. W starszych wersjach użyj Vector2(0, ProjectSettings.get_setting("physics/2d/default_gravity")) dla 2D lub Vector3(0, -ProjectSettings.get_setting("physics/3d/default_gravity"), 0) dla 3D.

6. Przegląd kluczowych właściwości

Zarówno CharacterBody2D, jak i CharacterBody3D mają te ważne właściwości. Dostosuj je w Inspektorze lub za pomocą kodu.

Właściwość Typ Domyślnie Opis
velocity Vector2 / Vector3 Vector2.ZERO Prędkość postaci. Ustaw ją przed wywołaniem move_and_slide(). Aktualizowana po wywołaniu wynikową prędkością.
floor_snap_length float 1.0 Zastępuje move_and_slide_with_snap(). Odległość przyciągania postaci do podłoża. Ustaw na 0, aby wyłączyć. Przydatne przy zboczach i schodach.
up_direction Vector2 / Vector3 Vector2.UP Definiuje, który kierunek jest „górą". To określa, co liczy się jako podłoga, ściana lub sufit. Domyślnie (0, -1) w 2D, (0, 1, 0) w 3D.
floor_stop_on_slope bool true Gdy true, postać nie ześlizguje się ze zboczy stojąc nieruchomo. Niezbędne w platformówkach.
floor_max_angle float 0.785 (45°) Maksymalny kąt zbocza, po którym można chodzić, w radianach. Powierzchnie bardziej strome są traktowane jak ściany. Użyj deg_to_rad(60), aby ustawić 60 stopni.
max_slides int 6 Maksymalna liczba iteracji kolizji na wywołanie move_and_slide(). Wyższe wartości są dokładniejsze, ale wolniejsze.
wall_min_slide_angle float 0.262 (15°) Minimalny kąt ślizgania po ścianie. Zapobiega zaklinowaniu się postaci na niemal równoległych ścianach.
platform_on_leave PlatformOnLeave ADD_VELOCITY Zachowanie przy opuszczaniu ruchomej platformy. ADD_VELOCITY zachowuje pęd, ADD_UPWARD_VELOCITY dodaje tylko składową w górę, DO_NOTHING ignoruje prędkość platformy.
slide_on_ceiling bool true Gdy true, pozwala na ślizganie się po sufitach. Gdy false, zatrzymuje prędkość poziomą przy uderzeniu w sufit.

7. Wykrywanie kolizji po move_and_slide()

Po wywołaniu move_and_slide() możesz zbadać kolizje, które wystąpiły. Jest to przydatne do reagowania na określone typy colliderów, odtwarzania efektów dźwiękowych przy lądowaniu lub implementacji mechaniki wall-jumpa.

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

Przydatne metody KinematicCollision

8. Ściąga migracyjna

Szybki punkt odniesienia do konwersji kodu z Godot 3 na 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(...)
zwraca prędkość
move_and_slide()
właściwość velocity jest aktualizowana w miejscu
var gravity = ProjectSettings.get("physics/2d/default_gravity") get_gravity() (4.4+)
move_and_slide(..., up_direction, ...) up_direction = Vector2.UP (ustawione jako właściwość)
move_and_slide(..., stop_on_slope, ...) floor_stop_on_slope = true (ustawione jako właściwość)
Automatyczny konwerter Godota

Przy otwieraniu projektu z Godot 3 w Godot 4 silnik proponuje konwersję twojego projektu. Zmienia nazwy węzłów i próbuje zaktualizować skrypty, ale nie zawsze poprawnie obsługuje wywołania move_and_slide(). Prawdopodobnie będziesz musiał ręcznie poprawić swój kod ruchu.

9. Typowe błędy

Błąd 1: Przekazywanie argumentów do move_and_slide()

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

Błąd 2: Zapomnienie o ustawieniu velocity przed move_and_slide()

Źle — velocity nigdy nie jest ustawiane, więc nic się nie porusza
func _physics_process(delta: float) -> void:
    move_and_slide()  # velocity is Vector2.ZERO — nothing happens

Błąd 3: Używanie _process() zamiast _physics_process()

move_and_slide() musi być wywoływane w _physics_process(), które działa ze stałą częstotliwością (domyślnie 60 Hz). Użycie _process() wiąże fizykę z liczbą klatek renderowania, powodując niespójne zachowanie.

Błąd 4: Brak konfiguracji CollisionShape

CharacterBody2D/CharacterBody3D bez potomka CollisionShape będzie przechodzić przez wszystko. Godot pokazuje ikonę ostrzeżenia w edytorze, jeśli kształt kolizji jest brakujący.

Błąd 5: Nadpisywanie velocity.y grawitacją w każdej klatce

Źle — resetuje velocity.y, więc skok nigdy nie działa
# This overwrites any jump velocity!
velocity.y = gravity * delta  # should be +=, not =
Poprawnie — akumuluje grawitację
# Gravity accumulates over time
velocity += get_gravity() * delta

Błąd 6: Stosowanie grawitacji, gdy postać jest na podłodze

Zawsze otaczaj grawitację warunkiem if not is_on_floor(). Bez tego sprawdzenia grawitacja akumuluje się dalej, gdy postać jest na podłodze. Gdy postać zejdzie z krawędzi, spadnie z ekstremalną prędkością zamiast spadać naturalnie.

10. Konfiguracja kontrolerów postaci z pomocą AI

Chcesz, żeby AI skonfigurowało twój kontroler postaci?

Godot MCP Pro pozwala asystentom AI tworzyć węzły CharacterBody, konfigurować właściwości fizyki, ustawiać kształty kolizji, pisać skrypty ruchu, uruchamiać twoją grę i testować ruch — wszystko za pomocą poleceń w języku naturalnym.

add_node setup_physics_body setup_collision set_physics_layers create_script simulate_key play_scene capture_frames
Zdobądź Godot MCP Pro — $15