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 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue