Added Smooth ass leaning and crouching... Wow. Impressed.

This commit is contained in:
Franklin Blanco 2023-09-16 10:28:48 -07:00
parent 0d07fa2329
commit da6f47e01f
6 changed files with 78 additions and 67 deletions

View File

@ -1,4 +1,4 @@
use bevy::{prelude::*, window::CursorGrabMode};
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use crate::logic::core::player::player_movement::{
@ -16,7 +16,7 @@ pub fn capture_input(
&mut ExternalImpulse,
&mut PlayerLinearYState,
&mut PlayerLinearXZState,
&Transform,
&mut Transform,
&mut Damping,
),
With<Player>,
@ -31,6 +31,8 @@ pub fn capture_input(
KeyCode::W,
KeyCode::C,
KeyCode::Space,
KeyCode::Q,
KeyCode::E,
]) || keyboard_input.any_just_released([
KeyCode::A,
KeyCode::S,
@ -38,6 +40,8 @@ pub fn capture_input(
KeyCode::W,
KeyCode::C,
KeyCode::Space,
KeyCode::Q,
KeyCode::E,
]) {
let player_movement_input = PlayerMovementInput {
up: keyboard_input.just_pressed(KeyCode::Space),
@ -52,30 +56,4 @@ pub fn capture_input(
};
move_player(player_movement_input, player_query, time);
}
}
pub fn capture_cursor(
mut windows: Query<&mut Window>,
btn: Res<Input<MouseButton>>,
key: Res<Input<KeyCode>>,
) {
let mut window = windows.single_mut();
if btn.just_pressed(MouseButton::Left) {
// if you want to use the cursor, but not let it leave the window,
// use `Confined` mode:
// window.cursor.grab_mode = CursorGrabMode::Confined;
// for a game that doesn't use the cursor (like a shooter):
// use `Locked` mode to keep the cursor in one place
window.cursor.grab_mode = CursorGrabMode::Locked;
// also hide the cursor
window.cursor.visible = false;
}
if key.just_pressed(KeyCode::Escape) {
window.cursor.grab_mode = CursorGrabMode::None;
// also hide the cursor
window.cursor.visible = true;
}
}
}

View File

@ -13,7 +13,7 @@ pub const PLAYER_GRAVITY_SCALE: f32 = 4.0;
pub const PLAYER_HEIGHT: f32 = 2.5;
pub const PLAYER_CAMERA_HEIGHT: f32 = 1.0;
pub const PLAYER_CROUCH_HEIGHT: f32 = 0.0;
pub const PLAYER_CROUCH_TIME_MS: u128 = 130;
pub const PLAYER_CROUCH_TIME_S: f32 = 0.6;
pub const PLAYER_LINEAR_DAMPING: f32 = 3.5;
pub const PLAYER_LINEAR_DAMPING_WHILE_JUMPING: f32 = 0.25;

View File

@ -1,9 +1,9 @@
use bevy::{input::mouse::MouseMotion, prelude::*};
use bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode};
//use bevy_rapier3d::prelude::*;
use crate::{
comps::core::markers::{camera::MainCamera, player::Player},
constants::player_values::{PLAYER_CAMERA_HEIGHT, PLAYER_CROUCH_HEIGHT, PLAYER_CROUCH_TIME_MS},
constants::player_values::{PLAYER_CAMERA_HEIGHT, PLAYER_CROUCH_HEIGHT, PLAYER_CROUCH_TIME_S}, utils::rad_deg::radians_from_degrees,
};
use super::player_movement::PlayerLinearXZState;
@ -39,47 +39,79 @@ pub fn update_camera_vertical_position(
if let PlayerLinearXZState::Crouched(since) = player_linear_xz_state {
// Lerp/Smooth out this movement
let delta = time.elapsed().as_millis() - since;
if delta > PLAYER_CROUCH_TIME_MS {
camera_transform.translation.y = PLAYER_CROUCH_HEIGHT;
} else {
// Starts at player_camera_height -> ends at player_crouch_height (Only works if player_crouch_height is 0)
camera_transform.translation.y =
PLAYER_CAMERA_HEIGHT * (1.0 - (delta as f32 / PLAYER_CROUCH_TIME_MS as f32))
}
let delta = time.elapsed().as_secs_f32() - since;
camera_transform.translation = camera_transform.translation.lerp(Vec3 { x: camera_transform.translation.x, y: PLAYER_CROUCH_HEIGHT, z: camera_transform.translation.z }, (delta / PLAYER_CROUCH_TIME_S).clamp(0.0, 1.0));
} else {
camera_transform.translation.y = PLAYER_CAMERA_HEIGHT;
// TODO: Add elapsed time to standup so that crouch time and standup time is the same.
camera_transform.translation = camera_transform.translation.lerp(Vec3 { x: camera_transform.translation.x, y: PLAYER_CAMERA_HEIGHT, z: camera_transform.translation.z }, time.delta_seconds().clamp(0.0, 1.0));
}
}
/// Handles looking around if cursor is locked
pub fn follow_cursor_with_camera(
settings: Res<MouseMovementSettings>,
primary_window: Query<&Window>,
mut primary_window: Query<&mut Window>,
mut motions: EventReader<MouseMotion>,
mut player_query: Query<&mut Transform, (With<Player>, Without<MainCamera>)>,
mut camera_query: Query<&mut Transform, (With<MainCamera>, Without<Player>)>,
//time: Res<Time>,
keyboard_input: Res<Input<KeyCode>>,
btn: Res<Input<MouseButton>>,
time: Res<Time>,
) {
if let Ok(window) = primary_window.get_single() {
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.iter() {
let window_scale = window.height().min(window.width());
pitch -= (settings.sensitivity * motion.delta.y * window_scale).to_radians();
yaw -= (settings.sensitivity * motion.delta.x * window_scale).to_radians();
}
pitch = pitch.clamp(-1.54, 1.54);
if let Ok(mut window) = primary_window.get_single_mut() {
if btn.just_pressed(MouseButton::Left) {
// if you want to use the cursor, but not let it leave the window,
// use `Confined` mode:
// window.cursor.grab_mode = CursorGrabMode::Confined;
// for a game that doesn't use the cursor (like a shooter):
// use `Locked` mode to keep the cursor in one place
window.cursor.grab_mode = CursorGrabMode::Locked;
// also hide the cursor
window.cursor.visible = false;
}
if keyboard_input.just_pressed(KeyCode::Escape) {
window.cursor.grab_mode = CursorGrabMode::None;
// also hide the cursor
window.cursor.visible = true;
}
let desired_rotation_quat =
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
for _camera_transform in camera_query.iter_mut() {
player_transform.rotation = desired_rotation_quat;
// headbob_camera(&mut camera_transform, time.delta_seconds_f64());
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.iter() {
let window_scale = window.height().min(window.width());
pitch -= (settings.sensitivity * motion.delta.y * window_scale).to_radians();
yaw -= (settings.sensitivity * motion.delta.x * window_scale).to_radians();
}
pitch = pitch.clamp(-1.54, 1.54);
let desired_rotation_quat =
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
for mut camera_transform in camera_query.iter_mut() {
player_transform.rotation = desired_rotation_quat;
if keyboard_input.pressed(KeyCode::Q) {
let final_quat = Quat::from_axis_angle(Vec3::Z, radians_from_degrees(30.0));
camera_transform.rotation = camera_transform.rotation.lerp(final_quat, time.delta_seconds() / 0.2);
} else if keyboard_input.pressed(KeyCode::E) {
let final_quat = Quat::from_axis_angle(Vec3::Z, radians_from_degrees(-30.0));
camera_transform.rotation = camera_transform.rotation.lerp(final_quat, time.delta_seconds() / 0.2);
} else {
camera_transform.rotation = camera_transform.rotation.lerp(Quat::default(), time.delta_seconds() / 0.2);
}
// headbob_camera(&mut camera_transform, time.delta_seconds_f64());
}
}
}
} else {
warn!("Primary window not found for `player_look`!");
}
}
fn lerp(final_vec: Vec3, current: Vec3, delta_time: f32, total_time: f32) -> Vec3 {
(final_vec - current) * (delta_time/total_time)
}

View File

@ -5,7 +5,7 @@ use crate::comps::core::markers::player::PlayerHand;
pub fn capture_hand_usage(
mouse_buttons: Res<Input<MouseButton>>,
mut query: Query<&mut Transform, With<PlayerHand>>,
time: Res<Time>,
//time: Res<Time>,
) {
for mut transform in query.iter_mut() {
if mouse_buttons.pressed(MouseButton::Left) {

View File

@ -42,7 +42,7 @@ impl PlayerLinearYState {
#[derive(Component, Default, Debug)]
pub enum PlayerLinearXZState {
Crouched(u128),
Crouched(f32),
Walking,
#[default]
Stopped,
@ -56,7 +56,7 @@ impl PlayerLinearXZState {
_ => false,
}
}
pub fn toggle_crouch(&mut self, time: u128) {
pub fn toggle_crouch(&mut self, time: f32) {
if let Self::Crouched(_) = self {
*self = Self::Stopped;
} else {
@ -111,7 +111,7 @@ pub fn move_player(
&mut ExternalImpulse,
&mut PlayerLinearYState,
&mut PlayerLinearXZState,
&Transform,
&mut Transform,
&mut Damping,
),
With<Player>,
@ -123,12 +123,12 @@ pub fn move_player(
mut player_external_force,
mut player_linear_y_state,
mut player_linear_xz_state,
player_transform,
mut player_transform,
mut player_damping,
) in &mut query
{
if player_movement_input.down {
player_linear_xz_state.toggle_crouch(time.elapsed().as_millis());
player_linear_xz_state.toggle_crouch(time.elapsed().as_secs_f32());
}
let crouch_multiplier = if player_linear_xz_state.is_crouched() {
PLAYER_CROUCH_SPEED_MULTIPLIER
@ -207,7 +207,8 @@ pub fn move_player(
}
if player_movement_input.lean_left {
//player_transform.rotation =
} else {}
if player_movement_input.up && player_linear_y_state.is_grounded(&PLAYER_JUMP_COOLDOWN_MS) {

View File

@ -1,7 +1,7 @@
use bevy::prelude::*;
use crate::{
comps::core::controller::{capture_cursor, capture_input},
comps::core::controller::capture_input,
logic::core::{
guns::spawn_firearm::spawn_firearm_on_player_hands,
player::{
@ -32,7 +32,7 @@ pub fn load_scene(application: &mut App) {
// Update
application.add_systems(Update, capture_input);
application.add_systems(Update, capture_cursor);
//application.add_systems(Update, capture_cursor);
application.add_systems(Update, sync_player_y_state);
application.add_systems(Update, follow_cursor_with_camera);
application.add_systems(Update, asset_loaded);