|
3 | 3 | //! - Copy the code for the `CameraControllerPlugin` and add the plugin to your App.
|
4 | 4 | //! - Attach the `CameraController` component to an entity with a `Camera3dBundle`.
|
5 | 5 |
|
| 6 | +use bevy::window::CursorGrabMode; |
6 | 7 | use bevy::{input::mouse::MouseMotion, prelude::*};
|
7 | 8 |
|
8 | 9 | use std::f32::consts::*;
|
9 | 10 | use std::fmt;
|
10 | 11 |
|
| 12 | +/// Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0, |
| 13 | +/// but I'm guessing it is a misunderstanding between degrees/radians and then sticking with |
| 14 | +/// it because it felt nice. |
| 15 | +pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0; |
| 16 | + |
11 | 17 | #[derive(Component)]
|
12 | 18 | pub struct CameraController {
|
13 | 19 | pub enabled: bool,
|
@@ -35,7 +41,7 @@ impl Default for CameraController {
|
35 | 41 | Self {
|
36 | 42 | enabled: true,
|
37 | 43 | initialized: false,
|
38 |
| - sensitivity: 0.5, |
| 44 | + sensitivity: 1.0, |
39 | 45 | key_forward: KeyCode::W,
|
40 | 46 | key_back: KeyCode::S,
|
41 | 47 | key_left: KeyCode::A,
|
@@ -91,12 +97,14 @@ impl Plugin for CameraControllerPlugin {
|
91 | 97 |
|
92 | 98 | fn camera_controller(
|
93 | 99 | time: Res<Time>,
|
| 100 | + mut windows: ResMut<Windows>, |
94 | 101 | mut mouse_events: EventReader<MouseMotion>,
|
95 | 102 | mouse_button_input: Res<Input<MouseButton>>,
|
96 | 103 | key_input: Res<Input<KeyCode>>,
|
97 | 104 | mut move_toggled: Local<bool>,
|
98 | 105 | mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
|
99 | 106 | ) {
|
| 107 | + let window = windows.primary_mut(); |
100 | 108 | let dt = time.delta_seconds();
|
101 | 109 |
|
102 | 110 | if let Ok((mut transform, mut options)) = query.get_single_mut() {
|
@@ -158,16 +166,22 @@ fn camera_controller(
|
158 | 166 | // Handle mouse input
|
159 | 167 | let mut mouse_delta = Vec2::ZERO;
|
160 | 168 | if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {
|
| 169 | + window.set_cursor_grab_mode(CursorGrabMode::Locked); |
| 170 | + window.set_cursor_visibility(false); |
| 171 | + |
161 | 172 | for mouse_event in mouse_events.iter() {
|
162 | 173 | mouse_delta += mouse_event.delta;
|
163 | 174 | }
|
| 175 | + } else { |
| 176 | + window.set_cursor_grab_mode(CursorGrabMode::None); |
| 177 | + window.set_cursor_visibility(true); |
164 | 178 | }
|
165 | 179 |
|
166 | 180 | if mouse_delta != Vec2::ZERO {
|
167 | 181 | // Apply look update
|
168 |
| - options.pitch = (options.pitch - mouse_delta.y * 0.5 * options.sensitivity * dt) |
| 182 | + options.pitch = (options.pitch - mouse_delta.y * RADIANS_PER_DOT * options.sensitivity) |
169 | 183 | .clamp(-PI / 2., PI / 2.);
|
170 |
| - options.yaw -= mouse_delta.x * options.sensitivity * dt; |
| 184 | + options.yaw -= mouse_delta.x * RADIANS_PER_DOT * options.sensitivity; |
171 | 185 | transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, options.yaw, options.pitch);
|
172 | 186 | }
|
173 | 187 | }
|
|
0 commit comments