From 42460a76fb571c3e69284982786ab9e04dd04b81 Mon Sep 17 00:00:00 2001 From: copygirl Date: Mon, 20 Oct 2025 21:16:48 +0200 Subject: [PATCH] Use MeshRayCast to render debug ray --- src/main.rs | 9 +++++++++ src/placement.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/placement.rs diff --git a/src/main.rs b/src/main.rs index 69eef41..865f2ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,20 @@ use bevy::prelude::*; mod free_camera; use free_camera::*; +mod placement; +use placement::*; + fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, (camera_free_look, noclip_controller).chain()) + // This system requires `GlobalTransform`, so for a most + // up-to-date value, run it right after it's been updated. + .add_systems( + PostUpdate, + debug_ray_cast.after(TransformSystems::Propagate), + ) .run(); } diff --git a/src/placement.rs b/src/placement.rs new file mode 100644 index 0000000..1f1d302 --- /dev/null +++ b/src/placement.rs @@ -0,0 +1,27 @@ +use bevy::prelude::*; +use bevy::window::{CursorGrabMode, CursorOptions}; + +pub fn debug_ray_cast( + mut gizmos: Gizmos, + mut ray_cast: MeshRayCast, + window: Single<(&Window, &CursorOptions)>, + camera: Single<(&GlobalTransform, &Camera)>, +) { + let (window, cursor) = window.into_inner(); + let (transform, camera) = camera.into_inner(); + + let ray = if cursor.grab_mode == CursorGrabMode::Locked { + Ray3d::new(transform.translation(), transform.forward()) + } else if let Some(cursor_pos) = window.cursor_position() { + camera.viewport_to_world(transform, cursor_pos).unwrap() + } else { + return; // cursor outside window area + }; + + let settings = &MeshRayCastSettings::default(); + let Some((_entity, hit)) = ray_cast.cast_ray(ray, settings).first() else { + return; // ray didn't hit anything + }; + + gizmos.arrow(hit.point, hit.point + hit.normal / 2., Color::WHITE); +}