diff --git a/Cargo.lock b/Cargo.lock index 1879459..9b53100 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,6 +747,8 @@ dependencies = [ "bevy_text", "bevy_time", "bevy_transform", + "bevy_ui", + "bevy_ui_render", "bevy_utils", "bevy_window", "bevy_winit", @@ -1223,6 +1225,68 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "bevy_ui" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa0fe27b8c641c2537480774dfd9198d56779371b04dd76618db39da4e7c7483" +dependencies = [ + "accesskit", + "bevy_a11y", + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_input", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_sprite", + "bevy_text", + "bevy_transform", + "bevy_utils", + "bevy_window", + "derive_more", + "smallvec", + "taffy", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "bevy_ui_render" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1d2e783bb5f0b748e6360a0055421d5c934b43830b205a84996a75e54330cd7" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_camera", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_platform", + "bevy_reflect", + "bevy_render", + "bevy_shader", + "bevy_sprite", + "bevy_sprite_render", + "bevy_text", + "bevy_transform", + "bevy_ui", + "bevy_utils", + "bytemuck", + "derive_more", + "tracing", +] + [[package]] name = "bevy_utils" version = "0.17.3" @@ -2174,6 +2238,12 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "grid" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a" + [[package]] name = "guillotiere" version = "0.6.2" @@ -3649,6 +3719,18 @@ dependencies = [ "libc", ] +[[package]] +name = "taffy" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4f4d046dd956a47a7e1a2947083d7ac3e6aa3cfaaead36173ceaa5ab11878c" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + [[package]] name = "termcolor" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index 9f14753..a1ff4fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ all-features = true [features] dev = ["bevy/dynamic_linking", "bevy/file_watcher", "bevy/embedded_watcher"] debug = ["bevy/debug", "bevy_egui", "bevy/bevy_text"] -fly_camera = [] +fly_camera = ["bevy/bevy_text", "bevy/bevy_ui", "bevy/bevy_ui_render", "bevy/default_font"] [dependencies] bevy = { version = "0.17.3", default-features = false, features = [ diff --git a/src/fly_camera.rs b/src/fly_camera.rs index 33d45ad..762343f 100644 --- a/src/fly_camera.rs +++ b/src/fly_camera.rs @@ -1,10 +1,17 @@ //! Camera movement logic based on +//! +//! See [`KeyBindings`] as to how to use this plugin. use bevy::{ input::mouse::MouseMotion, prelude::*, window::{CursorGrabMode, CursorOptions, PrimaryWindow}, }; +/// The duration for which the [`SpeedLabel`] is visible, in seconds. +/// +/// It indicates the current speed value after you pressed `speed_increase` or `speed_decrease`. +const SPEED_LABEL_VISIBLE_DURATION: f32 = 2.0; + /// A marker component used in queries when you want flycams and not other cameras #[derive(Component)] pub struct FlyCam; @@ -12,26 +19,30 @@ pub struct FlyCam; /// Configuration for which keyboard keys control which action /// Mouse is used for rotating the camera. /// Keyboard is used for moving the camera around. +/// +/// You can press the Space key ([`toggle_grab_cursor`]) to toggle mouse control on/off. #[derive(Resource)] pub struct KeyBindings { - /// The [`KeyCode`] that increases the speed of the movement of the camera. + /// The [`KeyCode`] that increases the speed of the movement of the camera + /// (default: [`KeyCode::Digit2`]). pub speed_increase: KeyCode, - /// The [`KeyCode`] that decreases the speed of the movement of the camera. + /// The [`KeyCode`] that decreases the speed of the movement of the camera + /// (default: [`KeyCode::Digit1`]). pub speed_decrease: KeyCode, - /// The [`KeyCode`] that moves the camera forward. + /// The [`KeyCode`] that moves the camera forward (default: [`KeyCode::KeyW`]). pub move_forward: KeyCode, - /// The [`KeyCode`] that moves the camera backward. + /// The [`KeyCode`] that moves the camera backward (default: [`KeyCode::KeyS`]). pub move_backward: KeyCode, - /// The [`KeyCode`] that moves the camera left. + /// The [`KeyCode`] that moves the camera left (default: [`KeyCode::KeyA`]). pub move_left: KeyCode, - /// The [`KeyCode`] that moves the camera right. + /// The [`KeyCode`] that moves the camera right (default: [`KeyCode::KeyD`]). pub move_right: KeyCode, - /// The [`KeyCode`] that moves the camera upward. + /// The [`KeyCode`] that moves the camera upward (default: [`KeyCode::KeyR`]). pub move_ascend: KeyCode, - /// The [`KeyCode`] that moves the camera downward. + /// The [`KeyCode`] that moves the camera downward (default: [`KeyCode::KeyF`]). pub move_descend: KeyCode, /// The [`KeyCode`] that toggles between mouse (rotational) and keyboard (translational) - /// control. + /// control (default: [`KeyCode::Space`]). pub toggle_grab_cursor: KeyCode, } @@ -44,8 +55,8 @@ impl Default for KeyBindings { move_backward: KeyCode::KeyS, move_left: KeyCode::KeyA, move_right: KeyCode::KeyD, - move_ascend: KeyCode::Space, - move_descend: KeyCode::ShiftLeft, + move_ascend: KeyCode::KeyR, + move_descend: KeyCode::KeyF, toggle_grab_cursor: KeyCode::Space, } } @@ -172,25 +183,83 @@ fn player_look( } fn cursor_grab( + mut commands: Commands, keys: Res>, key_bindings: Res, primary_cursor_options: Single<&mut CursorOptions, With>, settings: Option>, + mut help_text: Query<(Entity, &mut SpeedLabel)>, ) { if keys.just_pressed(key_bindings.toggle_grab_cursor) { toggle_grab_cursor(primary_cursor_options); } if let Some(mut settings) = settings { + let mut speed_changed = false; + if keys.just_pressed(key_bindings.speed_increase) { settings.speed *= 2.0; + speed_changed = true; } if keys.just_pressed(key_bindings.speed_decrease) { settings.speed /= 2.0; + speed_changed = true; + } + + if speed_changed { + if let Some(mut h) = help_text.iter_mut().next() { + h.1.time_to_live = SPEED_LABEL_VISIBLE_DURATION; + } else { + spawn_speed_text_node(&mut commands); + } + } + } +} + +#[derive(Component)] +struct SpeedLabel { + pub time_to_live: f32, +} + +fn animate_text( + mut commands: Commands, + time: Res