diff --git a/Design.md b/Design.md index b8de35d..d34086f 100644 --- a/Design.md +++ b/Design.md @@ -16,13 +16,25 @@ Make sure guns are usable with iron sights. Multiplayer -# TODOS: +# TODOs: - [ ] Detach player rotation from character model - [ ] Weapon Sway - [ ] Fixing leaning + - [ ] Bring Crouching back - [ ] Inspect animation (procedural) - [ ] Reload animation (procedural) - [ ] Real world magazines - [ ] Rewriting bullet physics to use raycasts & kinematic rigidbodies (logic controlled) - [ ] Low Ready & High ready (low ready == more speed | high ready == more accuracy) - - [ ] Auto Low ready when gun collider hits object OR when player starts sprinting \ No newline at end of file + - [ ] Auto Low ready when gun collider hits object OR when player starts sprinting + + +# Design + +- Detach player rotation from character model +Don't parent the hands to the camera +Make the hands move to the camera with a delay + lerp +On player movement: +WASD -> Translate player parent objetc, everything else follows +Mouse movements -> Rotate camera (on all axises) + Player Character (Not parent object) on only the horizontal axis (Z I think) +What moves first is the camera, then the entire body moves with a lerp \ No newline at end of file diff --git a/src/logic/core/player/camera_player_sync.rs b/src/logic/core/player/camera_player_sync.rs index e7026bd..11d509b 100644 --- a/src/logic/core/player/camera_player_sync.rs +++ b/src/logic/core/player/camera_player_sync.rs @@ -123,86 +123,102 @@ pub fn follow_cursor_with_camera( if window.cursor.grab_mode != CursorGrabMode::None { for mut player_transform in player_query.iter_mut() { - let (mut yaw, mut pitch, _) = player_transform.rotation.to_euler(EulerRot::YXZ); - for motion in motions.read() { - let window_scale = window.height().min(window.width()); - if btn.pressed(MouseButton::Right) { - pitch -= ((settings.aimed_sensitivity - * motion.delta.y as f64 - * window_scale as f64) as f32) - .to_radians(); - yaw -= ((settings.aimed_sensitivity - * motion.delta.x as f64 - * window_scale as f64) as f32) - .to_radians(); - } else { - pitch -= ((settings.sensitivity - * motion.delta.y as f64 - * window_scale as f64) as f32) - .to_radians(); - yaw -= - ((settings.sensitivity * motion.delta.x as f64 * window_scale as f64) - as f32) - .to_radians(); - } - } - pitch = pitch.clamp(-1.54, 1.54); - - let desired_rotation_quat = - (Quat::from_axis_angle(Vec3::Y, yaw) * -1. )* Quat::from_axis_angle(Vec3::X, pitch); + for mut camera_transform in camera_query.iter_mut() { + let (mut yaw, mut pitch) = (player_transform.rotation.to_euler(EulerRot::YXZ).0, camera_transform.rotation.to_euler(EulerRot::YXZ).1) ; + for motion in motions.read() { + let window_scale = window.height().min(window.width()); + if btn.pressed(MouseButton::Right) { + pitch -= ((settings.aimed_sensitivity + * motion.delta.y as f64 + * window_scale as f64) as f32) + .to_radians(); + yaw -= ((settings.aimed_sensitivity + * motion.delta.x as f64 + * window_scale as f64) as f32) + .to_radians(); + } else { + pitch -= ((settings.sensitivity + * motion.delta.y as f64 + * window_scale as f64) as f32) + .to_radians(); + yaw -= + ((settings.sensitivity * motion.delta.x as f64 * window_scale as f64) + as f32) + .to_radians(); + } + } + pitch = pitch.clamp(-1.54, 1.54); + + let desired_rotation_quat_camera = + Quat::from_axis_angle(Vec3::X, pitch); + + let desired_rotation_quat_player = Quat::from_axis_angle(Vec3::Y, yaw) * -1. ; + let local_z = camera_transform.local_z(); let right = Vec3::new(local_z.z, camera_transform.translation.y, -local_z.x); - player_transform.rotation = desired_rotation_quat; + camera_transform.rotation = desired_rotation_quat_camera; if keyboard_input.pressed(KeyCode::Q) { - let final_quat = Quat::from_axis_angle( - Vec3::Z, - radians_from_degrees(player_values_state.player_lean_angle), - ); - camera_transform.rotation = camera_transform.rotation.lerp( - final_quat, - time.delta_seconds() / player_values_state.player_lean_time, - ); - camera_transform.translation = camera_transform.translation.lerp( + let mut eulers = desired_rotation_quat_player.to_euler(EulerRot::XYZ); + eulers.2 = eulers.2 + player_values_state.player_lean_angle.to_radians(); + let mut new_rot = player_transform.rotation.lerp( + Quat::from_euler(EulerRot::XYZ, eulers.0, eulers.1, eulers.2), + time.delta_seconds() / player_values_state.player_lean_time, + ).to_euler(EulerRot::XYZ); + new_rot.1 = eulers.1; + player_transform.rotation = Quat::from_euler(EulerRot::XYZ, new_rot.0, new_rot.1, new_rot.2); + /*player_transform.translation = player_transform.translation.lerp( Vec3 { x: -right.x, - y: camera_transform.translation.y, + y: player_transform.translation.y, z: -right.z, }, time.delta_seconds() / player_values_state.player_lean_time, - ); + );*/ } else if keyboard_input.pressed(KeyCode::E) { - let final_quat = Quat::from_axis_angle( - Vec3::Z, - radians_from_degrees(-player_values_state.player_lean_angle), - ); - camera_transform.rotation = camera_transform.rotation.lerp( - final_quat, - time.delta_seconds() / player_values_state.player_lean_time, - ); - camera_transform.translation = camera_transform.translation.lerp( - Vec3 { - x: right.x, - y: camera_transform.translation.y, - z: right.z, - }, - time.delta_seconds() / player_values_state.player_lean_time, - ); + let mut eulers = desired_rotation_quat_player.to_euler(EulerRot::XYZ); + eulers.2 = eulers.2 + (player_values_state.player_lean_angle.to_radians() * -1.0); + let mut new_rot = player_transform.rotation.lerp( + Quat::from_euler(EulerRot::XYZ, eulers.0, eulers.1, eulers.2), + time.delta_seconds() / player_values_state.player_lean_time, + ).to_euler(EulerRot::XYZ); + new_rot.1 = eulers.1; + player_transform.rotation = Quat::from_euler(EulerRot::XYZ, new_rot.0, new_rot.1, new_rot.2); } else { - camera_transform.rotation = camera_transform.rotation.lerp( + /*camera_transform.rotation = camera_transform.rotation.lerp( Quat::default(), time.delta_seconds() / player_values_state.player_lean_time, - ); + );*/ - camera_transform.translation = camera_transform.translation.lerp( + /*let camera_rotation_to_follow: Vec3 = camera_transform.rotation.to_euler(EulerRot::XYZ).into(); // Move player Only on Y axis + let mut original_rotation_in_euler: Vec3 = original_rotation.to_euler(EulerRot::XYZ).into(); + original_rotation_in_euler.y = camera_rotation_to_follow.y; + + original_rotation = Quat::from_euler(EulerRot::XYZ, original_rotation_in_euler.x, original_rotation_in_euler.y, original_rotation_in_euler.z);*/ + + let mut eulers = desired_rotation_quat_player.to_euler(EulerRot::XYZ); + eulers.2 = eulers.2 + 0.0f32.to_radians(); + let mut new_rot = player_transform.rotation.lerp( + Quat::from_euler(EulerRot::XYZ, eulers.0, eulers.1, eulers.2), + time.delta_seconds() / player_values_state.player_lean_time, + ).to_euler(EulerRot::XYZ); + new_rot.1 = eulers.1; + // TODO: fix fast snap rotation back to 0 + player_transform.rotation = Quat::from_euler(EulerRot::XYZ, new_rot.0, new_rot.1, new_rot.2); + player_transform.rotation = desired_rotation_quat_player; + + //println!("Player EulerRot Y: {} Camera EulerRot Y: {}", player_transform.rotation.to_euler(EulerRot::XYZ).1, camera_transform.rotation.to_euler(EulerRot::XYZ).1); + + //camera_transform.rotation = desired_rotation_quat; + /*camera_transform.translation = camera_transform.translation.lerp( Vec3 { x: 0.0, y: camera_transform.translation.y, z: 0.0, }, time.delta_seconds() / player_values_state.player_lean_time, - ); + );*/ } } } diff --git a/src/main.rs b/src/main.rs index e8950dd..1b5dc05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ fn setup_plugins(application: &mut App) { .add_plugins(DefaultPlugins.set(AssetPlugin::default())) //.add_plugins(DefaultInspectorConfigPlugin) .add_plugins(RapierPhysicsPlugin::::default()) - .add_plugins(RapierDebugRenderPlugin::default()) + //.add_plugins(RapierDebugRenderPlugin::default()) .add_plugins(ComponentsFromGltfPlugin) //.add_plugins(bevy_egui::EguiPlugin) //.add_plugins(WorldInspectorPlugin::new())