Expand description
Provides physics world management, colliders, and raycasting functionalities using the Rapier physics engine.
§Features
- Colliders: Add physics colliders to entities for collision detection (see
Colliderfor supported shapes) - Raycasting: Cast rays through the physics world to detect intersections (see
PhysicsWorldfor raycasting methods) - Automatic Updates: Colliders automatically sync with entity transforms
§Creating Colliders
Attach a collider component to any entity with a transform:
commands.spawn((
Transform::from_xyz(0.0, -1.0, 0.0),
Collider::from(CuboidCollider::new(Vec3::new(10.0, 1.0, 10.0)).with_group(ColliderGroup::GROUP_1)),
));This example creates a large flat collider representing the ground, assigned to GROUP_1. You can create various shapes (e.g., boxes, spheres, heightfields) and assign them to different groups for selective raycasting.
§Raycasting
Cast rays to detect physics intersections:
fn cast_ray_system(phworld: Res<PhysicsWorld>) {
let ray = Ray::new(
Vec3::new(0.0, 10.0, 0.0), // Origin above the ground
Vec3::new(0.0, -1.0, 0.0), // Direction pointing downwards
);
// Cast the ray and check for hits
// Use a filter to only hit colliders in GROUP_1
if let Some((entity, toi)) = phworld.cast_ray(&ray, &RayCastConfig::with_filter(ColliderGroup::GROUP_1)) {
let hit_point = ray.point_at(toi);
println!("Hit entity {:?} at {:?}", entity, hit_point);
}
}§Camera-Based Raycasting
Cast rays from screen coordinates (useful for mouse picking):
fn mouse_picking(
mut commands: Commands,
phworld: Res<PhysicsWorld>,
window: Single<&Window, With<PrimaryWindow>>,
camera_query: Query<(&GlobalTransform, &CameraView), With<Camera>>,
) {
// Get cursor position in NDC
let Some(cursor_pos) = window.cursor_position() else { return };
let cursor_ndc = cursor_pos / window.size();
// Get camera data
let Ok((camera_transform, camera_view)) = camera_query.get_single() else { return };
let aspect_ratio = window.size().x / window.size().y;
// Create ray from camera
let ray = Ray::from_ndc(cursor_ndc, aspect_ratio, camera_transform, camera_view);
// Cast the ray
if let Some((entity, toi)) = phworld.cast_ray(&ray, &RayCastConfig::default()) {
let hit_point = ray.point_at(toi);
println!("Clicked on entity {:?} at {:?}", entity, hit_point);
}
}