From 8286da7743fa79b905036a7607ab9859989126ae Mon Sep 17 00:00:00 2001 From: janis Date: Thu, 9 Oct 2025 22:56:31 +0200 Subject: [PATCH 1/3] change walk_speed scaling to avoid sticking to zero/negative speeds --- crates/bevy_camera_controller/src/free_cam.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/bevy_camera_controller/src/free_cam.rs b/crates/bevy_camera_controller/src/free_cam.rs index 54ad1b8687224..0cbc32190f157 100644 --- a/crates/bevy_camera_controller/src/free_cam.rs +++ b/crates/bevy_camera_controller/src/free_cam.rs @@ -186,17 +186,25 @@ pub fn run_freecam_controller( return; } - let mut scroll = 0.0; - let amount = match accumulated_mouse_scroll.unit { MouseScrollUnit::Line => accumulated_mouse_scroll.delta.y, MouseScrollUnit::Pixel => { accumulated_mouse_scroll.delta.y / MouseScrollUnit::SCROLL_UNIT_CONVERSION_FACTOR } }; - scroll += amount; - controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed; - controller.run_speed = controller.walk_speed * 3.0; + + if amount != 0.0 { + // scale the speed exponentially with the scroll factor as the base. + let scroll_plus_one = controller.scroll_factor.max(0.0) + 1.0; + let log_speed_plus_one = bevy_math::ops::ln(controller.walk_speed + 1.0); + // `factor` will approach but never reach 0 as `walk_speed` approaches 0: + // Importantly, we want to avoid ever reaching exactly 0 so we don't get stuck there. + let factor = bevy_math::ops::powf(scroll_plus_one, log_speed_plus_one) - 0.999; + controller.walk_speed += factor * amount; + // avoid negative speeds. + controller.walk_speed = controller.walk_speed.clamp(0.0, f32::MAX); + controller.run_speed = controller.walk_speed * 3.0; + } // Handle key input let mut axis_input = Vec3::ZERO; From c74cedcc4eeb7ce82944bb107dac150fa39624fa Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 10 Oct 2025 17:15:20 +0200 Subject: [PATCH 2/3] simplify walk_speed logic as suggested by iquick --- crates/bevy_camera_controller/src/free_cam.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/bevy_camera_controller/src/free_cam.rs b/crates/bevy_camera_controller/src/free_cam.rs index 0cbc32190f157..a46f031d903b2 100644 --- a/crates/bevy_camera_controller/src/free_cam.rs +++ b/crates/bevy_camera_controller/src/free_cam.rs @@ -194,15 +194,8 @@ pub fn run_freecam_controller( }; if amount != 0.0 { - // scale the speed exponentially with the scroll factor as the base. - let scroll_plus_one = controller.scroll_factor.max(0.0) + 1.0; - let log_speed_plus_one = bevy_math::ops::ln(controller.walk_speed + 1.0); - // `factor` will approach but never reach 0 as `walk_speed` approaches 0: - // Importantly, we want to avoid ever reaching exactly 0 so we don't get stuck there. - let factor = bevy_math::ops::powf(scroll_plus_one, log_speed_plus_one) - 0.999; - controller.walk_speed += factor * amount; - // avoid negative speeds. - controller.walk_speed = controller.walk_speed.clamp(0.0, f32::MAX); + let factor = bevy_math::ops::exp(controller.scroll_factor * amount); + controller.walk_speed = (controller.walk_speed * factor).clamp(0.0, f32::MAX); controller.run_speed = controller.walk_speed * 3.0; } From 9af89130db9582fad8267f4eb666d9518497dbfe Mon Sep 17 00:00:00 2001 From: janis Date: Sat, 11 Oct 2025 19:24:15 +0200 Subject: [PATCH 3/3] move run_speed outside of amount check in case walk_speed was changed manually --- crates/bevy_camera_controller/src/free_cam.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_camera_controller/src/free_cam.rs b/crates/bevy_camera_controller/src/free_cam.rs index a46f031d903b2..aed1941cea4a8 100644 --- a/crates/bevy_camera_controller/src/free_cam.rs +++ b/crates/bevy_camera_controller/src/free_cam.rs @@ -196,8 +196,8 @@ pub fn run_freecam_controller( if amount != 0.0 { let factor = bevy_math::ops::exp(controller.scroll_factor * amount); controller.walk_speed = (controller.walk_speed * factor).clamp(0.0, f32::MAX); - controller.run_speed = controller.walk_speed * 3.0; } + controller.run_speed = controller.walk_speed * 3.0; // Handle key input let mut axis_input = Vec3::ZERO;