Quick answer: RigidBody2D falls through floors when the object moves fast enough to skip past the collision shape in a single physics frame. This is called tunneling. It commonly happens with thin floor collision shapes, high gravity values, or low physics tick rates.
Here is how to fix RigidBody2D falling through floor Godot 4. Your RigidBody2D objects hit the floor and everything works fine — until they do not. At some point, a fast-moving projectile, a falling crate, or your player character drops straight through a platform as if it were not there. This is physics tunneling, and it is one of the most frustrating issues in 2D game physics. Here is exactly why it happens in Godot 4 and how to fix it permanently.
The Symptom
A RigidBody2D node falls through a StaticBody2D or TileMap collision shape. The object simply passes through the surface without any collision response. It might happen consistently at high fall speeds, or intermittently during normal gameplay depending on frame timing.
The behavior is speed-dependent: objects moving slowly collide correctly, but past a certain velocity threshold they phase through. You might also notice that the problem is worse on lower-end machines or when the game’s frame rate drops, because the physics tick rate effectively decreases relative to the object’s speed.
In some cases, the tunneling only happens with specific collision shape combinations. A RigidBody2D with a CircleShape2D might pass through a thin WorldBoundaryShape2D but collide correctly with a thick RectangleShape2D. This inconsistency is a strong indicator that tunneling is the root cause rather than a misconfigured collision layer.
What Causes This
Godot’s default physics engine uses discrete collision detection. This means it checks for overlaps at the object’s position at each physics tick. If an object moves fast enough that its position at tick N is above the floor and its position at tick N+1 is below the floor, the engine never detects the overlap because the object was never inside the floor — it jumped over it entirely.
The tunneling threshold depends on three factors:
- Object velocity — The faster the object moves, the larger the gap between position checks.
- Physics tick rate — At 60 Hz (the default), each tick is ~16.67ms. An object moving at 1200 pixels/second travels 20 pixels per tick. If the floor collision shape is thinner than 20 pixels, it can be skipped entirely.
- Collision shape thickness — Thin shapes are easier to tunnel through. A WorldBoundaryShape2D has zero thickness, making it the most vulnerable. A RectangleShape2D with 32 pixels of height requires much higher speeds to tunnel through.
The math is straightforward: if velocity * delta > collision_shape_thickness, tunneling becomes possible. At the default 60 Hz tick rate with a 4-pixel-thick floor, any object moving faster than 240 pixels per second can potentially fall through.
The Fix
Step 1: Enable Continuous Collision Detection (CCD). CCD makes the physics engine sweep the object along its path between ticks, checking for collisions along the entire trajectory rather than only at discrete positions.
# Enable CCD on your RigidBody2D
extends RigidBody2D
func _ready():
continuous_cd = RigidBody2D.CCD_MODE_CAST_RAY
You can also set this in the Inspector under RigidBody2D → Continuous Cd. The two CCD modes are:
CCD_MODE_CAST_RAY— Casts a ray along the object’s movement direction. Fast and sufficient for most cases.CCD_MODE_CAST_SHAPE— Sweeps the entire collision shape along the path. More accurate but more expensive. Use this for large or oddly-shaped objects.
Step 2: Thicken your floor collision shapes. Even with CCD, thicker collision shapes provide a safety margin. Replace thin collision shapes with RectangleShape2D shapes that have meaningful height:
# If you're creating collision shapes in code
var shape = RectangleShape2D.new()
shape.size = Vector2(960, 16) # 16px thick, not 2px
var collision = CollisionShape2D.new()
collision.shape = shape
floor_body.add_child(collision)
For TileMap-based floors, ensure your physics layer collision shapes span the full tile height rather than using a thin line at the surface.
Step 3: Increase the physics tick rate for high-speed games. If your game involves very fast projectiles or extreme velocities, increase the tick rate in Project Settings:
# In Project Settings → Physics → Common
# Physics Ticks Per Second: 120
#
# Or set it in code at runtime:
Engine.physics_ticks_per_second = 120
Doubling the tick rate to 120 Hz halves the distance traveled per tick, effectively doubling the speed threshold for tunneling. The cost is additional CPU usage for physics calculations.
Step 4: Clamp maximum velocity. As a safety net, cap your object’s velocity to a value that cannot tunnel through your thinnest collision shape:
func _integrate_forces(state):
var max_speed = 800.0 # Safe for 16px shapes at 60 Hz
if state.linear_velocity.length() > max_speed:
state.linear_velocity = state.linear_velocity.normalized() * max_speed
Why This Works
CCD eliminates the gap between discrete position checks. Instead of only checking "is the object overlapping something at its current position," it asks "did the object cross through anything between its last position and its current position." This catches collisions that discrete detection misses entirely.
Thicker collision shapes increase the distance an object must travel in a single tick to tunnel through. A 16-pixel-thick floor at 60 Hz requires the object to move at 960 pixels/second to tunnel — four times the speed needed to tunnel through a 4-pixel shape.
Higher tick rates reduce the per-tick travel distance. At 120 Hz, the same object traveling at 1200 pixels/second only moves 10 pixels per tick instead of 20, making it much harder to skip past collision shapes.
Velocity clamping provides a hard guarantee. If you know the thickness of your thinnest collision shape and your physics tick rate, you can calculate the exact maximum safe velocity and enforce it. This is your last line of defense against tunneling edge cases.
"The combination of CCD and thicker collision shapes has been bulletproof for us. We have not seen a single tunneling report since making the change."
Related Issues
Tunneling is the 2D cousin of RigidBody3D passing through walls at high speeds, which uses the same CCD approach but with additional considerations for 3D physics substeps. If your objects are not falling through floors but are instead vibrating when stacked, that is a different problem related to solver iterations and sleeping thresholds. And if collision detection works but your Area2D signals are not firing, you likely have a collision layer/mask mismatch rather than a tunneling issue.
No more phantom floors. Physics you can trust.