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:
Aceeri 2022-12-27 00:34:06 +00:00
parent 741a91ed46
commit 5566d73d9e

View file

@ -3,11 +3,17 @@
//! - Copy the code for the `CameraControllerPlugin` and add the plugin to your App.
//! - Attach the `CameraController` component to an entity with a `Camera3dBundle`.
use bevy::window::CursorGrabMode;
use bevy::{input::mouse::MouseMotion, prelude::*};
use std::f32::consts::*;
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)]
pub struct CameraController {
pub enabled: bool,
@ -35,7 +41,7 @@ impl Default for CameraController {
Self {
enabled: true,
initialized: false,
sensitivity: 0.5,
sensitivity: 1.0,
key_forward: KeyCode::W,
key_back: KeyCode::S,
key_left: KeyCode::A,
@ -91,12 +97,14 @@ impl Plugin for CameraControllerPlugin {
fn camera_controller(
time: Res<Time>,
mut windows: ResMut<Windows>,
mut mouse_events: EventReader<MouseMotion>,
mouse_button_input: Res<Input<MouseButton>>,
key_input: Res<Input<KeyCode>>,
mut move_toggled: Local<bool>,
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
) {
let window = windows.primary_mut();
let dt = time.delta_seconds();
if let Ok((mut transform, mut options)) = query.get_single_mut() {
@ -158,16 +166,22 @@ fn camera_controller(
// Handle mouse input
let mut mouse_delta = Vec2::ZERO;
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() {
mouse_delta += mouse_event.delta;
}
} else {
window.set_cursor_grab_mode(CursorGrabMode::None);
window.set_cursor_visibility(true);
}
if mouse_delta != Vec2::ZERO {
// 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.);
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);
}
}