Debug-renderer
Rapier is a physics engine, it doesn't render anything. What is displayed by your application comes from your own renderer, and game assets generally don’t match the shapes seen by the physics engine exactly. Therefore a collider given the wrong size, a joint attached at the wrong place, or a rigid-body that is not where its sprite is, can be difficult to debug (and easy to misinterpret as physics-engine-bugs).
To help with debugging physics, Rapier’s debug-renderer exists to convert the content of the physics scene into a set of colored lines that your application to obtain a wireframe view of what Rapier actually sees.
The debug-renderer is behind the debug-render-2d and debug-render-3d cargo features (the one matching the
dimension of the crate is enabled by default, and can also be enabled with the debug-render alias). The
rapier-debug-render feature enables the debug-render pipeline of Rapier alone, without any Bevy rendering dependency,
in case you want to implement your own DebugRenderBackend.
The debug-renderer is enabled by adding the RapierDebugRenderPlugin to your app. It
draws the lines with the gizmos of Bevy, after the propagation of the transforms, for every physics context. The
plugin is also where the initial DebugRenderStyle (the colors and various length properties) and DebugRenderMode
(what is drawn, so you can select only the element types you are interested in debugging) are given. Use
RapierDebugRenderPlugin::default().disabled() to add the plugin without rendering anything until it is enabled:
.add_plugins(RapierDebugRenderPlugin {
// Only draw the collider shapes and the joints.
mode: DebugRenderMode::COLLIDER_SHAPES
| DebugRenderMode::IMPULSE_JOINTS
| DebugRenderMode::MULTIBODY_JOINTS,
..default()
})
After initialization, the debug-renderer is controlled by the DebugRenderContext resource:
enabledswitches the debug-rendering on and off.modeselects what is drawn, with one boolean per flag ofDebugRenderMode(so it can be edited by the tools based on Bevy's reflection, like the other fields of this resource).stylegives the colors and the lengths of the lines.default_collider_debugselects whether the collider shapes are drawn by default (ColliderDebug::AlwaysRender) or only for the colliders asking for it (ColliderDebug::NeverRender).scale_lengths_by_length_unit(enabled by default) makes the lengths of thestyleexpressed in meters: they are multiplied by the length unit of each physics context, e.g., by the pixels-per-meter in 2D.
fn modify_debug_render(mut debug_render: ResMut<DebugRenderContext>) {
// Toggle the debug-renderer.
debug_render.enabled = !debug_render.enabled;
// Draw the contacts and the AABBs too.
debug_render.mode.contacts = true;
debug_render.mode.collider_aabbs = true;
// Expressed in meters: multiplied by the length unit of each context.
debug_render.style.rigid_body_axes_length = 1.0;
}
Finally, the rendering of individual objects can be customized by adding the following components to their entities:
ColliderDebugColoroverrides the color of the collider (and of its AABB).ColliderDebugoverrides thedefault_collider_debugof theDebugRenderContextfor this collider (its shape, its AABB, and the contact pairs it is involved in).DebugRenderColoroverrides the color of everything attached to the entity: its collider (unless it has aColliderDebugColor), its rigid-body axes, its joint, and its soft-body.DebugRenderVisibility::Hiddenhides everything attached to the entity (except a collider with aColliderDebugcomponent).
- Example 2D
- Example 3D
// This collider is drawn in red.
commands.spawn((
Transform::from_xyz(0.0, 400.0, 0.0),
RigidBody::Dynamic,
Collider::ball(50.0),
ColliderDebugColor(Hsla::hsl(0.0, 1.0, 0.5)),
));
// Everything attached to this entity (its collider, its rigid-body, its joint, etc.) is
// drawn in blue.
commands.spawn((
Transform::from_xyz(200.0, 400.0, 0.0),
RigidBody::Dynamic,
Collider::cuboid(50.0, 50.0),
DebugRenderColor(Hsla::hsl(220.0, 1.0, 0.3)),
));
// Nothing attached to this entity is drawn.
commands.spawn((
Transform::from_xyz(-200.0, 400.0, 0.0),
RigidBody::Dynamic,
Collider::cuboid(50.0, 50.0),
DebugRenderVisibility::Hidden,
));
// The shape of this collider is never drawn, whatever the `default_collider_debug`.
commands.spawn((
Transform::from_xyz(-400.0, 400.0, 0.0),
Collider::cuboid(50.0, 50.0),
ColliderDebug::NeverRender,
));
// This collider is drawn in red.
commands.spawn((
Transform::from_xyz(0.0, 4.0, 0.0),
RigidBody::Dynamic,
Collider::ball(0.5),
ColliderDebugColor(Hsla::hsl(0.0, 1.0, 0.5)),
));
// Everything attached to this entity (its collider, its rigid-body, its joint, etc.) is
// drawn in blue.
commands.spawn((
Transform::from_xyz(2.0, 4.0, 0.0),
RigidBody::Dynamic,
Collider::cuboid(0.5, 0.5, 0.5),
DebugRenderColor(Hsla::hsl(220.0, 1.0, 0.3)),
));
// Nothing attached to this entity is drawn.
commands.spawn((
Transform::from_xyz(-2.0, 4.0, 0.0),
RigidBody::Dynamic,
Collider::cuboid(0.5, 0.5, 0.5),
DebugRenderVisibility::Hidden,
));
// The shape of this collider is never drawn, whatever the `default_collider_debug`.
commands.spawn((
Transform::from_xyz(-4.0, 4.0, 0.0),
Collider::cuboid(0.5, 0.5, 0.5),
ColliderDebug::NeverRender,
));
The debug-rendering is not free: it walks every collider of the scene and converts its shape into lines at each frame. Therefore it is meant to be enabled only when debugging rather than a player-facing representation of the game objects.