Skip to content

Debug Overlays ​

Tick Physics debug in the Game view (or press F4) during Play to draw collider wireframes and the lines your scripts draw over the scene - the fastest way to see whether your collision geometry is where you think it is, and what forces a script is applying.

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 ​

Tick Physics debug in the Game view's top-right corner, beside Maximise on Play (it stays when the game is maximised), or press F4 in the Viewport, while playing. The checkbox appears only when the running game has something physical (a Collider, RigidBody or Ragdoll) or a script draws debug lines; F4 works either way. One toggle draws four things at once:

The ⓘ stats overlay, the other debug readout in the viewport, open below the Scene view's button column.

ColourWhat it showsSource
YellowEvery collider of a moving (dynamic, RigidBody) object, at its real physics pose: a car, a crate, a ball. Static scenery is left out, since drawn whole it hides everything else.debugDynamic()
CyanEvery trigger (sensor) collider in the world, at its real physics pose.debugTriggers()
GreenThe collider the character is currently blocked against (walls, steps, obstacles), at its real physics pose.debugLines()

| Any | Lines your scripts draw with api.debugLine, in the colour they give. | PlayController.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.

Drawing your own: api.debugLine ​

A script draws a world-space line with api.debugLine(x1, y1, z1, x2, y2, z2, r?, g?, b?) (colour 0–1, default white). It shows only while Physics debug is on, and nothing is drawn in a shipped game, so the calls can stay in your code. A line drawn in onFixedUpdate stays until the next frame that runs a fixed step, so lines drawn at 60 steps a second do not blink on a 120 Hz display. One drawn in onUpdate lasts that frame. At most 20,000 segments a frame are kept.

ts
onFixedUpdate(api: ScriptApi, dt: number) {
  const p = api.getPosition(), v = api.getVelocity(api.entity);
  if (v) api.debugLine(p.x, p.y + 1, p.z, p.x + v.x * 0.2, p.y + 1 + v.y * 0.2, p.z + v.z * 0.2, 1, 1, 1); // velocity
}

Under the hood - debugLines, debugTriggers, contact entities ​

The overlay is built from three runner methods, each of which is empty before Play (no sim):

  • debugDynamic() - wireframe line geometry for every collider of a dynamic body, recoloured yellow.
  • 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.

The physics overlay shares the Viewport's line-overlay channel with other editor gizmos:

A selected crate in the Scene view: its collider drawn as a wireframe box around the mesh, with the move gizmo.

  • Selection collider gizmos (edit and Play) - green wireframes for the selected object's colliders, drawn from the ECS Collider data 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 ​

Awaken: browser-native WebGPU game engine.