Godot Physics: Body Types, Layers, Masks, and a Debugging Order

Choose the correct Godot physics body, configure collision layers and masks, move CharacterBody safely, and debug missing contacts in a repeatable order.

Abstract physics and motion visualization
On this page

Godot physics becomes manageable when four decisions stay separate: which node owns movement, which layer describes each object, which masks create detection paths, and which callback updates the simulation. Most confusing collision bugs happen because those decisions are mixed together and changed at random.

Quick Answer: Choose the Body by Responsibility

Use StaticBody for world geometry that does not move through gameplay code. Use CharacterBody for controlled actors whose velocity and collision response are authored in scripts. Use RigidBody when the physics engine should integrate forces, impulses, mass, and contacts. Use Area when you need overlap detection without solid body response.

That choice is about responsibility, not visual appearance. A door might be StaticBody while closed, AnimatableBody when moved as a platform, or Area when it is only a trigger. A projectile can be CharacterBody when you need precise authored movement or RigidBody when physical deflection is part of the design.

StaticBody, CharacterBody, RigidBody, or Area

StaticBody2D and StaticBody3D are stable collision surfaces such as floors, walls, and level geometry. Moving them by repeatedly changing transforms can produce surprising interactions. When a platform must move predictably and carry characters, consider AnimatableBody and follow the movement rules described by the physics documentation.

CharacterBody2D and CharacterBody3D are moved by your script. They are not pushed around automatically by gravity or friction; your code calculates those effects and calls move_and_slide() or move_and_collide(). In return, they provide floor, wall, slope, slide, and platform information suitable for players and authored enemies.

RigidBody2D and RigidBody3D belong to the solver. Apply forces or impulses instead of replacing transforms each frame. Area2D and Area3D detect bodies or other areas entering and leaving, making them useful for pickups, checkpoints, damage volumes, water regions, and proximity logic. The collision layer guide goes deeper on common detector setups.

Layers Say What You Are; Masks Say What You Scan

Signature lab · Collision matrix

Make the collision decision visible

Layer means what a body is. Mask means what it scans.

Player
Layer · what it is
Mask · what it scans
Pickup
Layer · what it is
Mask · what it scans
A matching mask exists, but monitoring is disabledMatch the Player vs Pickup preset and keep monitoring enabled on both sides.

Treat each collision layer as a named identity. World, Player, Enemy, Pickup, Hitbox, and Hurtbox are easier to reason about than unexplained bit numbers. A Player can belong to the Player layer while its mask scans World and Pickup. A Pickup belongs to Pickup and may scan Player so its Area reports the overlap.

Detection can be one-way. A hitbox can scan hurtboxes without requiring every hurtbox to scan hitboxes. Solid collision response and Area monitoring introduce additional behavior, so do not assume that one checked box creates every signal you need. Use the matrix below to inspect both directions deliberately.

  • Layer answers: what category does this collision object belong to?
  • Mask answers: which categories should this object scan?
  • Monitoring answers: should this Area actively report overlaps?
  • Monitorable answers: may other Areas discover this Area?

Move CharacterBody in the Physics Tick

Read player intent from named Input Map actions, update velocity, then call the body movement method from _physics_process(). CharacterBody's move_and_slide() uses the physics step internally. Multiplying velocity by delta before assigning it to the built-in velocity property is a common migration mistake because velocity is already expressed per second.

gdscript
extends CharacterBody2D

@export var speed := 280.0
@export var acceleration := 2200.0
@export var gravity := 1350.0
@export var jump_velocity := -420.0

func _physics_process(delta: float) -> void:
    var direction := Input.get_axis("move_left", "move_right")
    velocity.x = move_toward(velocity.x, direction * speed, acceleration * delta)

    if not is_on_floor():
        velocity.y += gravity * delta
    elif Input.is_action_just_pressed("jump"):
        velocity.y = jump_velocity

    move_and_slide()

The movement method updates collision state used by is_on_floor(), is_on_wall(), and slide collision queries. Read those results after movement when you need information from the current step. Keep visual smoothing, camera effects, and non-physics UI work outside the body movement responsibility.

The same ownership applies in 3D with CharacterBody3D and Vector3 velocity. Axis names, floor direction, slope behavior, and camera-relative input differ, but the architecture remains: named intent enters, the character script owns velocity, and the physics tick applies movement.

Debug Missing Collisions in This Order

Start with the Remote scene tree and confirm both runtime objects exist. Then make collision shapes visible and verify that each CollisionShape has a valid shape resource, is enabled, and overlaps where expected. A perfectly configured mask cannot detect a shape that is missing, disabled, scaled strangely, or attached to the wrong body.

Next inspect body types and movement ownership. Directly setting position can bypass the CharacterBody collision path you expected. Moving a RigidBody like a CharacterBody fights the solver. Calling movement from the render frame creates timing inconsistencies. Correct those architectural errors before toggling layers repeatedly.

Then read the layer and mask relationship in both directions. Confirm monitoring for Areas and confirm the signal belongs to the object you connected. Finally, inspect code timing and whether the callback signature matches the emitted signal. This order moves from physical existence to configuration to event handling, which prevents blind checkbox debugging.

Build Player, World, Pickup, and Hitbox Rules

Create named layers for World, Player, Pickup, Hitbox, and Hurtbox. Put the CharacterBody player on Player and let it scan World. Put the pickup Area on Pickup and let it scan Player. Put an attack Area on Hitbox and let it scan Hurtbox. Keep the player's solid body separate from its hurtbox if combat filtering needs different rules.

Test one relationship at a time. First confirm Player collides with World. Then confirm Pickup reports Player. Then confirm Hitbox reports Hurtbox without triggering on World or Pickup. Record the expected detector for each pair. The interactive matrix above makes that table explicit before you copy it into project settings.

If movement input is still entangled with collision debugging, use the Input Playground to verify named actions independently. If body ownership feels unclear, compare the node responsibilities in the interactive Physics Guide before expanding the scene.

Practice and Sources

Complete the Player vs Pickup target in the collision matrix, then reproduce it in a tiny project with visible collision shapes. Explain which object scans which layer and which node owns the response. The official sources below cover body behavior and movement APIs; this guide turns those pieces into a decision and debugging workflow.

Frequently asked questions

Which Godot body should a player use?
Use CharacterBody2D or CharacterBody3D when gameplay code controls movement and needs reliable wall, floor, and slide information.
What is the difference between collision layers and masks?
A layer describes what an object is. A mask describes which layers that object scans for collision or overlap relationships.
Why does move_and_slide belong in physics_process?
CharacterBody movement and collision should run on the fixed physics tick so the physics simulation receives consistent updates.
Verification notes

Sources and revision context

Rewritten to separate body responsibility, layer identity, mask scanning, movement timing, and contact debugging. Examples use CharacterBody2D but identify the matching 3D concepts.