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 bevy_rapier3d::prelude::*;
use crate::logic::core::player::player_movement::{ use crate::logic::core::player::player_movement::{
@ -16,7 +16,7 @@ pub fn capture_input(
&mut ExternalImpulse, &mut ExternalImpulse,
&mut PlayerLinearYState, &mut PlayerLinearYState,
&mut PlayerLinearXZState, &mut PlayerLinearXZState,
&Transform, &mut Transform,
&mut Damping, &mut Damping,
), ),
With<Player>, With<Player>,
@ -31,6 +31,8 @@ pub fn capture_input(
KeyCode::W, KeyCode::W,
KeyCode::C, KeyCode::C,
KeyCode::Space, KeyCode::Space,
KeyCode::Q,
KeyCode::E,
]) || keyboard_input.any_just_released([ ]) || keyboard_input.any_just_released([
KeyCode::A, KeyCode::A,
KeyCode::S, KeyCode::S,
@ -38,6 +40,8 @@ pub fn capture_input(
KeyCode::W, KeyCode::W,
KeyCode::C, KeyCode::C,
KeyCode::Space, KeyCode::Space,
KeyCode::Q,
KeyCode::E,
]) { ]) {
let player_movement_input = PlayerMovementInput { let player_movement_input = PlayerMovementInput {
up: keyboard_input.just_pressed(KeyCode::Space), up: keyboard_input.just_pressed(KeyCode::Space),
@ -53,29 +57,3 @@ pub fn capture_input(
move_player(player_movement_input, player_query, time); 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_HEIGHT: f32 = 2.5;
pub const PLAYER_CAMERA_HEIGHT: f32 = 1.0; pub const PLAYER_CAMERA_HEIGHT: f32 = 1.0;
pub const PLAYER_CROUCH_HEIGHT: f32 = 0.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: f32 = 3.5;
pub const PLAYER_LINEAR_DAMPING_WHILE_JUMPING: f32 = 0.25; 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 bevy_rapier3d::prelude::*;
use crate::{ use crate::{
comps::core::markers::{camera::MainCamera, player::Player}, 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; use super::player_movement::PlayerLinearXZState;
@ -39,47 +39,79 @@ pub fn update_camera_vertical_position(
if let PlayerLinearXZState::Crouched(since) = player_linear_xz_state { if let PlayerLinearXZState::Crouched(since) = player_linear_xz_state {
// Lerp/Smooth out this movement // Lerp/Smooth out this movement
let delta = time.elapsed().as_millis() - since; let delta = time.elapsed().as_secs_f32() - since;
if delta > PLAYER_CROUCH_TIME_MS { 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));
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))
}
} else { } 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 /// Handles looking around if cursor is locked
pub fn follow_cursor_with_camera( pub fn follow_cursor_with_camera(
settings: Res<MouseMovementSettings>, settings: Res<MouseMovementSettings>,
primary_window: Query<&Window>, mut primary_window: Query<&mut Window>,
mut motions: EventReader<MouseMotion>, mut motions: EventReader<MouseMotion>,
mut player_query: Query<&mut Transform, (With<Player>, Without<MainCamera>)>, mut player_query: Query<&mut Transform, (With<Player>, Without<MainCamera>)>,
mut camera_query: Query<&mut Transform, (With<MainCamera>, Without<Player>)>, 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() { if let Ok(mut window) = primary_window.get_single_mut() {
for mut player_transform in player_query.iter_mut() { if btn.just_pressed(MouseButton::Left) {
let (mut yaw, mut pitch, _) = player_transform.rotation.to_euler(EulerRot::YXZ); // if you want to use the cursor, but not let it leave the window,
for motion in motions.iter() { // use `Confined` mode:
let window_scale = window.height().min(window.width()); // window.cursor.grab_mode = CursorGrabMode::Confined;
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 = // for a game that doesn't use the cursor (like a shooter):
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch); // use `Locked` mode to keep the cursor in one place
window.cursor.grab_mode = CursorGrabMode::Locked;
// also hide the cursor
window.cursor.visible = false;
}
for _camera_transform in camera_query.iter_mut() { if keyboard_input.just_pressed(KeyCode::Escape) {
player_transform.rotation = desired_rotation_quat; window.cursor.grab_mode = CursorGrabMode::None;
// headbob_camera(&mut camera_transform, time.delta_seconds_f64()); // also hide the cursor
window.cursor.visible = true;
}
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 { } else {
warn!("Primary window not found for `player_look`!"); 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( pub fn capture_hand_usage(
mouse_buttons: Res<Input<MouseButton>>, mouse_buttons: Res<Input<MouseButton>>,
mut query: Query<&mut Transform, With<PlayerHand>>, mut query: Query<&mut Transform, With<PlayerHand>>,
time: Res<Time>, //time: Res<Time>,
) { ) {
for mut transform in query.iter_mut() { for mut transform in query.iter_mut() {
if mouse_buttons.pressed(MouseButton::Left) { if mouse_buttons.pressed(MouseButton::Left) {

View File

@ -42,7 +42,7 @@ impl PlayerLinearYState {
#[derive(Component, Default, Debug)] #[derive(Component, Default, Debug)]
pub enum PlayerLinearXZState { pub enum PlayerLinearXZState {
Crouched(u128), Crouched(f32),
Walking, Walking,
#[default] #[default]
Stopped, Stopped,
@ -56,7 +56,7 @@ impl PlayerLinearXZState {
_ => false, _ => false,
} }
} }
pub fn toggle_crouch(&mut self, time: u128) { pub fn toggle_crouch(&mut self, time: f32) {
if let Self::Crouched(_) = self { if let Self::Crouched(_) = self {
*self = Self::Stopped; *self = Self::Stopped;
} else { } else {
@ -111,7 +111,7 @@ pub fn move_player(
&mut ExternalImpulse, &mut ExternalImpulse,
&mut PlayerLinearYState, &mut PlayerLinearYState,
&mut PlayerLinearXZState, &mut PlayerLinearXZState,
&Transform, &mut Transform,
&mut Damping, &mut Damping,
), ),
With<Player>, With<Player>,
@ -123,12 +123,12 @@ pub fn move_player(
mut player_external_force, mut player_external_force,
mut player_linear_y_state, mut player_linear_y_state,
mut player_linear_xz_state, mut player_linear_xz_state,
player_transform, mut player_transform,
mut player_damping, mut player_damping,
) in &mut query ) in &mut query
{ {
if player_movement_input.down { 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() { let crouch_multiplier = if player_linear_xz_state.is_crouched() {
PLAYER_CROUCH_SPEED_MULTIPLIER PLAYER_CROUCH_SPEED_MULTIPLIER
@ -207,7 +207,8 @@ pub fn move_player(
} }
if player_movement_input.lean_left { if player_movement_input.lean_left {
//player_transform.rotation =
} else {} } else {}
if player_movement_input.up && player_linear_y_state.is_grounded(&PLAYER_JUMP_COOLDOWN_MS) { 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 bevy::prelude::*;
use crate::{ use crate::{
comps::core::controller::{capture_cursor, capture_input}, comps::core::controller::capture_input,
logic::core::{ logic::core::{
guns::spawn_firearm::spawn_firearm_on_player_hands, guns::spawn_firearm::spawn_firearm_on_player_hands,
player::{ player::{
@ -32,7 +32,7 @@ pub fn load_scene(application: &mut App) {
// Update // Update
application.add_systems(Update, capture_input); 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, sync_player_y_state);
application.add_systems(Update, follow_cursor_with_camera); application.add_systems(Update, follow_cursor_with_camera);
application.add_systems(Update, asset_loaded); application.add_systems(Update, asset_loaded);