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: 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 Stamina (with bar?)
- [ ] 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 {
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),
right: keyboard_input.pressed(KeyCode::D),
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_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_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_WHILE_JUMPING: f32 = 0.25;

View File

@ -3,7 +3,7 @@ use bevy::{input::mouse::MouseMotion, prelude::*};
use crate::{
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;
@ -28,13 +28,21 @@ impl Default for MouseMovementSettings {
pub fn sync_camera_to_player(
mut player: Query<(&mut Transform, &PlayerLinearXZState), (With<Player>, Without<MainCamera>)>,
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 camera_transform) = camera.get_single_mut() else { return };
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;
} 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 {
camera_transform.translation.y += PLAYER_CAMERA_HEIGHT;
}

View File

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