bevy_dev/debug_camera/
controller.rs1use std::f32::consts::PI;
2
3use bevy::{
4 input::mouse::{MouseMotion, MouseWheel},
5 prelude::*,
6};
7
8#[cfg(feature = "ui")]
9use crate::ui::popup::{PopupEvent, PopupPosition};
10
11use super::{DebugCamera, DebugCameraControls, DebugCameraData};
12
13const MOUSE_LOOK_X_LIMIT: f32 = PI / 2.0;
14const RESET_SPEED_THRESHOLD_IN_SECONDS: f32 = 0.2;
15
16pub(super) fn system(
17 mut cameras: Query<(
18 &mut Transform,
19 &mut DebugCameraData,
20 &mut DebugCamera,
21 &Camera,
22 )>,
23 mut mouse_motion: EventReader<MouseMotion>,
24 mut mouse_wheel: EventReader<MouseWheel>,
25 time: Res<Time>,
26 keys: Res<ButtonInput<KeyCode>>,
27 controls: Res<DebugCameraControls>,
28 #[cfg(feature = "ui")] mut popup_event: EventWriter<PopupEvent>,
29) {
30 let (mut transform, mut data, mut debug_camera, _) =
31 match cameras.iter_mut().find(|x| x.3.is_active) {
32 Some(v) => v,
33 None => return,
34 };
35
36 for input in mouse_wheel.read() {
38 data.speed_level += input.y;
39 data.speed_level = data.speed_level.clamp(
40 (debug_camera.speed_multiplier_range.start().log2() * 4.0).floor(),
41 (debug_camera.speed_multiplier_range.end().log2() * 4.0).ceil(),
42 );
43
44 debug_camera.speed_multiplier = 2.0f32.powf(data.speed_level * 0.25).clamp(
45 *debug_camera.speed_multiplier_range.start(),
46 *debug_camera.speed_multiplier_range.end(),
47 );
48
49 #[cfg(feature = "ui")]
50 {
51 let value = debug_camera.speed_multiplier;
52 popup_event.write(PopupEvent::new(
53 PopupPosition::BelowCenter,
54 0.5,
55 move |ui| {
56 ui.label(format!("Speed multiplier: {:.2}", value));
57 },
58 ));
59 }
60 }
61
62 let mut translation = Vec3::ZERO;
64 if keys.pressed(controls.move_forward) {
65 translation -= Vec3::from(transform.local_z());
66 }
67 if keys.pressed(controls.move_backward) {
68 translation += Vec3::from(transform.local_z());
69 }
70 if keys.pressed(controls.move_left) {
71 translation -= Vec3::from(transform.local_x());
72 }
73 if keys.pressed(controls.move_right) {
74 translation += Vec3::from(transform.local_x());
75 }
76 if keys.pressed(controls.move_up) {
77 translation += Vec3::Y;
78 }
79 if keys.pressed(controls.move_down) {
80 translation -= Vec3::Y;
81 }
82
83 transform.translation += translation.normalize_or_zero()
84 * (data.current_speed * debug_camera.speed_multiplier * time.delta_secs());
85
86 for input in mouse_motion.read() {
88 let (mut y, mut x, _) = transform.rotation.to_euler(EulerRot::YXZ);
89
90 x -= (input.delta.y * debug_camera.sensitivity).to_radians();
91 x = x.clamp(-MOUSE_LOOK_X_LIMIT, MOUSE_LOOK_X_LIMIT);
92
93 y -= (input.delta.x * debug_camera.sensitivity).to_radians();
94
95 transform.rotation = Quat::from_rotation_y(y) * Quat::from_rotation_x(x);
96 }
97
98 if translation != Vec3::ZERO {
100 data.current_speed += data.current_speed * time.delta_secs() * debug_camera.speed_increase;
101 data.last_change_position_time = time.elapsed_secs();
102 } else if data.last_change_position_time > RESET_SPEED_THRESHOLD_IN_SECONDS {
103 data.current_speed = debug_camera.base_speed;
104 }
105}