Nicer usage for scene viewer (#7035)
# Objective Scene viewer mouse sensitivity/cursor usage isn't the best it could be atm, so just adding some quick, maybe opinionated, tweaks to make it feel more at home in usage. ## Solution - Mouse delta shouldn't be affected by delta time, it should be more expected that if I move my mouse 1 inch to the right that it should move the in game camera/whatever is controlled the same regardless of FPS. - Uses a magic number of 180.0 for a nice default sensitivity, modeled after Valorant's default sensitivity. - Cursor now gets locked/hidden when rotating the camera to give it more of the effect that you are grabbing the camera.
This commit is contained in:
parent
741a91ed46
commit
5566d73d9e
@ -3,11 +3,17 @@
|
|||||||
//! - Copy the code for the `CameraControllerPlugin` and add the plugin to your App.
|
//! - Copy the code for the `CameraControllerPlugin` and add the plugin to your App.
|
||||||
//! - Attach the `CameraController` component to an entity with a `Camera3dBundle`.
|
//! - Attach the `CameraController` component to an entity with a `Camera3dBundle`.
|
||||||
|
|
||||||
|
use bevy::window::CursorGrabMode;
|
||||||
use bevy::{input::mouse::MouseMotion, prelude::*};
|
use bevy::{input::mouse::MouseMotion, prelude::*};
|
||||||
|
|
||||||
use std::f32::consts::*;
|
use std::f32::consts::*;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
/// Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0,
|
||||||
|
/// but I'm guessing it is a misunderstanding between degrees/radians and then sticking with
|
||||||
|
/// it because it felt nice.
|
||||||
|
pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct CameraController {
|
pub struct CameraController {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
@ -35,7 +41,7 @@ impl Default for CameraController {
|
|||||||
Self {
|
Self {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
sensitivity: 0.5,
|
sensitivity: 1.0,
|
||||||
key_forward: KeyCode::W,
|
key_forward: KeyCode::W,
|
||||||
key_back: KeyCode::S,
|
key_back: KeyCode::S,
|
||||||
key_left: KeyCode::A,
|
key_left: KeyCode::A,
|
||||||
@ -91,12 +97,14 @@ impl Plugin for CameraControllerPlugin {
|
|||||||
|
|
||||||
fn camera_controller(
|
fn camera_controller(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
mut windows: ResMut<Windows>,
|
||||||
mut mouse_events: EventReader<MouseMotion>,
|
mut mouse_events: EventReader<MouseMotion>,
|
||||||
mouse_button_input: Res<Input<MouseButton>>,
|
mouse_button_input: Res<Input<MouseButton>>,
|
||||||
key_input: Res<Input<KeyCode>>,
|
key_input: Res<Input<KeyCode>>,
|
||||||
mut move_toggled: Local<bool>,
|
mut move_toggled: Local<bool>,
|
||||||
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
|
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
|
||||||
) {
|
) {
|
||||||
|
let window = windows.primary_mut();
|
||||||
let dt = time.delta_seconds();
|
let dt = time.delta_seconds();
|
||||||
|
|
||||||
if let Ok((mut transform, mut options)) = query.get_single_mut() {
|
if let Ok((mut transform, mut options)) = query.get_single_mut() {
|
||||||
@ -158,16 +166,22 @@ fn camera_controller(
|
|||||||
// Handle mouse input
|
// Handle mouse input
|
||||||
let mut mouse_delta = Vec2::ZERO;
|
let mut mouse_delta = Vec2::ZERO;
|
||||||
if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {
|
if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {
|
||||||
|
window.set_cursor_grab_mode(CursorGrabMode::Locked);
|
||||||
|
window.set_cursor_visibility(false);
|
||||||
|
|
||||||
for mouse_event in mouse_events.iter() {
|
for mouse_event in mouse_events.iter() {
|
||||||
mouse_delta += mouse_event.delta;
|
mouse_delta += mouse_event.delta;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
window.set_cursor_grab_mode(CursorGrabMode::None);
|
||||||
|
window.set_cursor_visibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if mouse_delta != Vec2::ZERO {
|
if mouse_delta != Vec2::ZERO {
|
||||||
// Apply look update
|
// Apply look update
|
||||||
options.pitch = (options.pitch - mouse_delta.y * 0.5 * options.sensitivity * dt)
|
options.pitch = (options.pitch - mouse_delta.y * RADIANS_PER_DOT * options.sensitivity)
|
||||||
.clamp(-PI / 2., PI / 2.);
|
.clamp(-PI / 2., PI / 2.);
|
||||||
options.yaw -= mouse_delta.x * options.sensitivity * dt;
|
options.yaw -= mouse_delta.x * RADIANS_PER_DOT * options.sensitivity;
|
||||||
transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, options.yaw, options.pitch);
|
transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, options.yaw, options.pitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user