Added smooth crouch downards

This commit is contained in:
Franklin 2023-09-13 11:56:42 -04:00
parent b8fcb2d765
commit e362d6f9fa
5 changed files with 34 additions and 24 deletions

View File

@ -4,7 +4,7 @@
- [x] ~~Glitch: Fall does not remove linear damping, only after jump~~ - [x] ~~Glitch: Fall does not remove linear damping, only after jump~~
- [x] ~~Glitch: Negative linear damping on jump allows for bunny hopping~~ - [x] ~~Glitch: Negative linear damping on jump allows for bunny hopping~~
- [ ] Feature: Add smooth camera movement to camera on crouch. Right now it's too fast and looks arcade af. - [x] Feature: Add smooth camera movement to camera on crouch. Right now it's too fast and looks arcade af.
- [ ] Feature: Add jump effect to camera - [ ] Feature: Add jump effect to camera
- [ ] Feature: Add Stamina (with bar?) - [ ] Feature: Add Stamina (with bar?)
- [ ] Feature: Subtle Headbob, FOV change on movement (Distinguish between sprinting and walking). - [ ] Feature: Subtle Headbob, FOV change on movement (Distinguish between sprinting and walking).

View File

@ -41,7 +41,7 @@ pub fn capture_input(
]) { ]) {
let player_movement_input = PlayerMovementInput { let player_movement_input = PlayerMovementInput {
up: keyboard_input.just_pressed(KeyCode::Space), up: keyboard_input.just_pressed(KeyCode::Space),
down: keyboard_input.pressed(KeyCode::C), down: keyboard_input.just_pressed(KeyCode::C),
left: keyboard_input.pressed(KeyCode::A), left: keyboard_input.pressed(KeyCode::A),
right: keyboard_input.pressed(KeyCode::D), right: keyboard_input.pressed(KeyCode::D),
front: keyboard_input.pressed(KeyCode::W), front: keyboard_input.pressed(KeyCode::W),

View File

@ -8,9 +8,10 @@ pub const PLAYER_CROUCH_SPEED_MULTIPLIER: f32 = 0.25;
pub const PLAYER_INITIAL_WEIGHT: f32 = 75.0; pub const PLAYER_INITIAL_WEIGHT: f32 = 75.0;
pub const PLAYER_GRAVITY_SCALE: f32 = 4.0; pub const PLAYER_GRAVITY_SCALE: f32 = 4.0;
pub const PLAYER_HEIGHT: f32 = 2.0; 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_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

@ -3,7 +3,7 @@ use bevy::{input::mouse::MouseMotion, prelude::*};
use crate::{ use crate::{
comps::core::{camera::MainCamera, markers::player::Player}, comps::core::{camera::MainCamera, markers::player::Player},
constants::player_values::{PLAYER_CAMERA_HEIGHT, PLAYER_CROUCH_HEIGHT}, constants::player_values::{PLAYER_CAMERA_HEIGHT, PLAYER_CROUCH_HEIGHT, PLAYER_CROUCH_TIME_MS},
}; };
use super::player_movement::PlayerLinearXZState; use super::player_movement::PlayerLinearXZState;
@ -28,13 +28,21 @@ impl Default for MouseMovementSettings {
pub fn sync_camera_to_player( pub fn sync_camera_to_player(
mut player: Query<(&mut Transform, &PlayerLinearXZState), (With<Player>, Without<MainCamera>)>, mut player: Query<(&mut Transform, &PlayerLinearXZState), (With<Player>, Without<MainCamera>)>,
mut camera: Query<&mut Transform, (With<MainCamera>, Without<Player>)>, mut camera: Query<&mut Transform, (With<MainCamera>, Without<Player>)>,
time: Res<Time>,
) { ) {
let Ok((mut player, player_linear_xz_state)) = player.get_single_mut() else { return }; let Ok((mut player, player_linear_xz_state)) = player.get_single_mut() else { return };
let Ok(mut camera_transform) = camera.get_single_mut() else { return }; let Ok(mut camera_transform) = camera.get_single_mut() else { return };
camera_transform.translation = player.translation; camera_transform.translation = player.translation;
if player_linear_xz_state.is_crouched() { 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; 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; camera_transform.translation.y += PLAYER_CAMERA_HEIGHT;
} }

View File

@ -42,7 +42,7 @@ impl PlayerLinearYState {
#[derive(Component, Default, Debug)] #[derive(Component, Default, Debug)]
pub enum PlayerLinearXZState { pub enum PlayerLinearXZState {
Crouched, Crouched(u128),
Walking, Walking,
#[default] #[default]
Stopped, Stopped,
@ -52,10 +52,17 @@ pub enum PlayerLinearXZState {
impl PlayerLinearXZState { impl PlayerLinearXZState {
pub fn is_crouched(&self) -> bool { pub fn is_crouched(&self) -> bool {
match self { match self {
Self::Crouched => true, Self::Crouched(_) => true,
_ => false, _ => false,
} }
} }
pub fn toggle_crouch(&mut self, time: u128) {
if let Self::Crouched(_) = self {
*self = Self::Stopped;
} else {
*self = Self::Crouched(time);
}
}
pub fn is_sprinting(&self) -> bool { pub fn is_sprinting(&self) -> bool {
match self { match self {
Self::Sprinting => true, Self::Sprinting => true,
@ -110,13 +117,15 @@ pub fn move_player(
mut player_damping, mut player_damping,
) in &mut query ) in &mut query
{ {
let crouch_multiplier = if player_movement_input.down { if player_movement_input.down {
*player_linear_xz_state = PlayerLinearXZState::Crouched; player_linear_xz_state.toggle_crouch(time.elapsed().as_millis());
}
let crouch_multiplier = if player_linear_xz_state.is_crouched() {
PLAYER_CROUCH_SPEED_MULTIPLIER PLAYER_CROUCH_SPEED_MULTIPLIER
} else { } else {
1.0 1.0
}; };
let sprint_multiplier = if player_movement_input.sprint && !player_movement_input.down { let sprint_multiplier = if player_movement_input.sprint && !player_linear_xz_state.is_crouched() {
PLAYER_SPRINT_SPEED_MULTIPLIER PLAYER_SPRINT_SPEED_MULTIPLIER
} else { } else {
1.0 1.0
@ -129,9 +138,7 @@ pub fn move_player(
if player_movement_input.front { if player_movement_input.front {
if sprint_multiplier == PLAYER_SPRINT_SPEED_MULTIPLIER { if sprint_multiplier == PLAYER_SPRINT_SPEED_MULTIPLIER {
*player_linear_xz_state = PlayerLinearXZState::Sprinting; *player_linear_xz_state = PlayerLinearXZState::Sprinting;
} else if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER { } else if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER {} else {
*player_linear_xz_state = PlayerLinearXZState::Crouched;
} else {
*player_linear_xz_state = PlayerLinearXZState::Walking; *player_linear_xz_state = PlayerLinearXZState::Walking;
} }
player_velocity.linvel = apply_movement_acceleration_to_vec( player_velocity.linvel = apply_movement_acceleration_to_vec(
@ -142,9 +149,7 @@ pub fn move_player(
); );
} }
if player_movement_input.back { if player_movement_input.back {
if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER { if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER {} else {
*player_linear_xz_state = PlayerLinearXZState::Crouched;
} else {
*player_linear_xz_state = PlayerLinearXZState::Walking; *player_linear_xz_state = PlayerLinearXZState::Walking;
} }
player_velocity.linvel = apply_movement_acceleration_to_vec( player_velocity.linvel = apply_movement_acceleration_to_vec(
@ -155,9 +160,7 @@ pub fn move_player(
); );
} }
if player_movement_input.right { if player_movement_input.right {
if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER { if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER {} else {
*player_linear_xz_state = PlayerLinearXZState::Crouched;
} else {
*player_linear_xz_state = PlayerLinearXZState::Walking; *player_linear_xz_state = PlayerLinearXZState::Walking;
} }
player_velocity.linvel = apply_movement_acceleration_to_vec( player_velocity.linvel = apply_movement_acceleration_to_vec(
@ -172,9 +175,7 @@ pub fn move_player(
); );
} }
if player_movement_input.left { if player_movement_input.left {
if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER { if crouch_multiplier == PLAYER_CROUCH_SPEED_MULTIPLIER {} else {
*player_linear_xz_state = PlayerLinearXZState::Crouched;
} else {
*player_linear_xz_state = PlayerLinearXZState::Walking; *player_linear_xz_state = PlayerLinearXZState::Walking;
} }
player_velocity.linvel = apply_movement_acceleration_to_vec( player_velocity.linvel = apply_movement_acceleration_to_vec(
@ -224,7 +225,7 @@ pub fn move_player(
&& player_velocity.linvel.x < 1.0 && player_velocity.linvel.x < 1.0
&& player_velocity.linvel.z > -1.0 && player_velocity.linvel.z > -1.0
&& player_velocity.linvel.z < 1.0 && player_velocity.linvel.z < 1.0
&& !player_movement_input.down && !player_linear_xz_state.is_crouched()
{ {
*player_linear_xz_state = PlayerLinearXZState::Stopped; *player_linear_xz_state = PlayerLinearXZState::Stopped;
} }