Core Systems Quest

Physics Guide

Choose the right body type, collision layer, and movement API before tuning feel.

10-20 min Practice first Godot 4.6
Start here

Which body should I use?

Pick the body by ownership of motion first: you drive it, physics drives it, it blocks, or it only detects.

Goal Use Why
I move it with code and need collision response. CharacterBody2D You own velocity. Godot resolves sliding, floor checks, and wall contact.
The physics simulation should move it. RigidBody2D Apply forces or impulses, then let the physics server integrate motion.
It blocks movement but does not move. StaticBody2D Cheap, stable collision for level geometry and fixed obstacles.
It detects overlap but should not block. Area2D Use signals or overlap queries for pickups, hurt zones, sensors, and checkpoints.
It is a moving platform or conveyor. AnimatableBody2D Move it from code or animation while keeping predictable collision behavior.
Godot 4.6 note

Jolt Physics is the default 3D physics engine for new projects. The body-type decisions below still apply: CharacterBody for controlled movement, RigidBody for simulation, StaticBody for fixed collision, and Area for overlap detection.

You control motion

CharacterBody2D

Players, enemies, controllable NPCs
Unity habit to replace

Think of this as "Rigidbody2D plus CharacterController behavior." You set velocity, then call move_and_slide().

move_and_slide()

Default choice for platformers, top-down movement, slopes, and walls.

  • Updates is_on_floor() and is_on_wall()
  • Slides along surfaces automatically
  • Works with the built-in velocity property

move_and_collide()

Use when you need custom collision response.

  • Returns a KinematicCollision2D
  • You decide bounce, stop, redirect, or custom slide behavior
  • Better for unusual movement rules than normal characters

Platformer movement

player_platformer.gd
123456789101112131415161718
extends CharacterBody2D

@export var speed := 300.0
@export var jump_velocity := -420.0

var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")

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

    var direction := Input.get_axis("move_left", "move_right")
    velocity.x = direction * speed

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_velocity

    move_and_slide()
Practice next

Create a CharacterBody2D with a CollisionShape2D and Sprite2D. Add Input Map actions for move_left, move_right, and jump, then test floor and wall behavior.

Common mistakes

Fix these first when physics feels broken

  • Moving a RigidBody2D by setting position every frame instead of using forces, impulses, or a custom integrator.
  • Using Area2D for walls. Areas detect overlaps; they do not block characters.
  • Calling is_on_floor() before move_and_slide(). Floor and wall state is updated by the move call.
  • Putting movement in _process(delta) when it depends on physics collision. Use _physics_process(delta).
  • Forgetting CollisionShape2D nodes. A body without a shape does not meaningfully collide.
Tutor Checkpoint

Lock the pattern in

Before jumping to the next page, turn the idea into one tiny scene or script. That is where the Godot habit sticks.

Unity habit

Rigidbody habits do not map one-to-one to CharacterBody2D.

Unreal habit

Character movement is less prebuilt, but more explicit and scriptable.

Godot habit

Use CharacterBody for controlled actors, RigidBody for simulation, Area for detection.

Try this

Build a collision layer chart for player, enemy, world, trigger, and pickup.