use bevy::prelude::*; use bevy::input::mouse::MouseMotion; use bevy::window::PrimaryWindow; use std::{f32::consts::*, fmt}; use crate::audio; pub struct CameraControllerPlugin; impl Plugin for CameraControllerPlugin { fn build(&self, app: &mut App) { app.add_systems(Update, run_camera_controller); } } /// 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, pub initialized: bool, pub sensitivity: f32, pub key_forward: KeyCode, pub key_back: KeyCode, pub key_left: KeyCode, pub key_right: KeyCode, pub key_up: KeyCode, pub key_down: KeyCode, pub key_run: KeyCode, pub key_stop: KeyCode, pub mouse_key_cursor_grab: MouseButton, pub keyboard_key_toggle_cursor_grab: KeyCode, pub move_speed: f32, pub friction: f32, pub pitch: f32, pub yaw: f32, pub velocity: Vec3, } impl Default for CameraController { fn default() -> Self { Self { enabled: true, initialized: false, sensitivity: 0.5, key_forward: KeyCode::KeyW, key_back: KeyCode::KeyS, key_left: KeyCode::KeyA, key_right: KeyCode::KeyD, key_up: KeyCode::ShiftLeft, key_down: KeyCode::ControlLeft, key_run: KeyCode::KeyR, key_stop: KeyCode::Space, mouse_key_cursor_grab: MouseButton::Left, keyboard_key_toggle_cursor_grab: KeyCode::KeyM, move_speed: 1.0, friction: 0.1, pitch: 0.0, yaw: 0.0, velocity: Vec3::ZERO, } } } impl fmt::Display for CameraController { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, " Freecam Controls: Mouse\t- Move camera orientation {:?}\t- Hold to grab cursor {:?}\t- Toggle cursor grab {:?} & {:?}\t- Fly forward & backwards {:?} & {:?}\t- Fly sideways left & right {:?} & {:?}\t- Fly up & down {:?}\t- Fly faster while held", self.mouse_key_cursor_grab, self.keyboard_key_toggle_cursor_grab, self.key_forward, self.key_back, self.key_left, self.key_right, self.key_up, self.key_down, self.key_run, ) } } #[allow(clippy::too_many_arguments)] fn run_camera_controller( time: Res