Added Smooth ass leaning and crouching... Wow. Impressed.
This commit is contained in:
parent
0d07fa2329
commit
da6f47e01f
@ -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),
|
||||
@ -53,29 +57,3 @@ 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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
let desired_rotation_quat =
|
||||
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
|
||||
// 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;
|
||||
}
|
||||
|
||||
for _camera_transform in camera_query.iter_mut() {
|
||||
player_transform.rotation = desired_rotation_quat;
|
||||
// headbob_camera(&mut camera_transform, time.delta_seconds_f64());
|
||||
if keyboard_input.just_pressed(KeyCode::Escape) {
|
||||
window.cursor.grab_mode = CursorGrabMode::None;
|
||||
// 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 {
|
||||
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)
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user