Debug Overlays
Press F4 during Play to draw collider wireframes over the scene - the fastest way to see whether your collision geometry is where you think it is.
Why a physics overlay
Colliders are invisible. A common bug is a collider that has drifted off its mesh - an invisible wall in the wrong place, a trigger that never fires because it isn't where the object is. The F4 overlay renders the actual physics geometry at its real physics pose, so a wireframe that floats away from its mesh tells you immediately that the collider's transform is wrong.
The overlay is Play-only - colliders exist only while the simulation runs, so nothing draws in edit mode. (In edit mode the Viewport already draws green collider gizmos for the selected object and its descendants; the F4 overlay is the running-sim equivalent.)
Toggling it
Press F4 in the Viewport while playing. One toggle draws two things at once:
| Colour | What it shows | Source |
|---|---|---|
| Cyan | Every trigger (sensor) collider in the world, at its real physics pose. | debugTriggers() |
| Green | The collider the character is currently blocked against (walls, steps, obstacles), at its real physics pose. | debugLines() |
Mesh colliders are drawn too - the wireframe is Rapier's own tessellation of each collider, so a trimesh or convex hull shows its actual triangles, not a bounding box.
The "blocked by" label
When the character controller is pushing against something, a label appears at the top of the viewport naming the object(s) currently stopping the player - for example ⛔ blocked by: StoneWall. This maps the blocked collider's body back to its GameObject, so you know exactly which object is in the way. The label is steady rather than flickering: a blocked collider stays lit for about 1.5 seconds after last contact, so the wireframe and name don't blink on and off while the controller repeatedly resolves the same wall. Floor contacts (near-vertical normals) are deliberately excluded so a big ground mesh doesn't flood the overlay - only walls, steps, and obstacles are shown. Double-click the label to copy the object name.
📸 Screenshot - save as img/physics-debug-f4.png
Play mode with F4 on: a cyan trigger-volume wireframe near a doorway, a green wireframe on the wall the player is walking into, and the "⛔ blocked by: …" label at the top of the viewport.
Under the hood - debugLines, debugTriggers, contact entities
The overlay is built from three runner methods, each of which is empty before Play (no sim):
debugTriggers()- wireframe line geometry for every sensor collider, recoloured cyan. Lets you verify a trigger sits where you intend during Play.debugLines()- wireframe line geometry for the colliders the character last blocked against, recoloured bright green. Rather than rendering every collider in the world (unusable in a real scene), it draws only the current blockers.debugContactEntities()- the GameObjects behind those blocking bodies, deduplicated, used for the "blocked by" label.
Each returns a flat line-list of position + colour per vertex, ready for the renderer's line overlay. They allocate on each call, so they're strictly debug-only.
Related overlays
The physics overlay shares the Viewport's line-overlay channel with other editor gizmos:
- Selection collider gizmos (edit and Play) - green wireframes for the selected object's colliders, drawn from the ECS
Colliderdata rather than the running sim. - Camera frustum - drawn when a Camera is selected.
- Stats overlay (ⓘ) - draw calls, triangles, and animated-mesh counts.
For those and the viewport's other visual aids, see the Viewport page.
See also
- Viewport - the 3D window and its other overlays and gizmos.
- Colliders & Shapes - the trigger flag the cyan overlay reflects.
- Character Controller - what "blocked" means for the green overlay.
- Raycasts, Triggers & Events - react to the triggers you can now see.