Add Asset loader, added and configured various states
This commit is contained in:
@@ -1,164 +1,164 @@
|
||||
use std::f32::{EPSILON, consts::FRAC_PI_2};
|
||||
|
||||
use bevy::{input::mouse::MouseMotion, prelude::*};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{
|
||||
components::{
|
||||
camera::CameraPitch,
|
||||
player::{GravityDirection, JumpSpeed, MoveSpeed, PlayerDrag, PlayerForce, PlayerMotion, PlayerVelocity},
|
||||
tags::Player,
|
||||
},
|
||||
states::input::PlayerInputSystems,
|
||||
utils::{input::get_mouse_delta, rotation::get_alignment_rotation_preserve_twist},
|
||||
};
|
||||
|
||||
pub struct PlayerPlugin;
|
||||
|
||||
impl Plugin for PlayerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(PreUpdate, (keyboard_input, player_look).in_set(PlayerInputSystems));
|
||||
app.add_systems(Update, (apply_gravity, apply_forces, apply_motion, apply_drag).chain());
|
||||
app.add_systems(Update, align_with_gravity);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_forces(player: Single<(&mut PlayerVelocity, &PlayerForce), With<Player>>, time: Res<Time>) {
|
||||
let (mut vel, force) = player.into_inner();
|
||||
|
||||
vel.0 += force.0 * time.delta_secs();
|
||||
}
|
||||
|
||||
fn apply_gravity(
|
||||
player: Single<
|
||||
(
|
||||
&mut PlayerVelocity,
|
||||
&GravityDirection,
|
||||
&GravityScale,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut vel, dir, scale, output) = player.into_inner();
|
||||
let Some(grav) = dir.0.map(|d| d.as_vec3()) else {
|
||||
return;
|
||||
};
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
if !is_grounded {
|
||||
vel.0 += grav * scale.0 * 9.47 * time.delta_secs();
|
||||
} else {
|
||||
let dot = vel.0.dot(grav);
|
||||
if dot > EPSILON {
|
||||
vel.0 -= dot * grav;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_drag(player: Single<(&mut PlayerVelocity, &PlayerDrag), With<Player>>, time: Res<Time>) {
|
||||
let (mut vel, drag) = player.into_inner();
|
||||
vel.0 *= (1.0 - drag.0 * time.delta_secs()).max(0.0);
|
||||
}
|
||||
|
||||
fn apply_motion(
|
||||
player: Single<
|
||||
(
|
||||
&mut KinematicCharacterController,
|
||||
&Transform,
|
||||
&PlayerVelocity,
|
||||
&PlayerMotion,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut controller, transform, vel, motion) = player.into_inner();
|
||||
// let max_vel = vel.0.clamp_length_max(500.0);
|
||||
let global_motion = transform.rotation * motion.0;
|
||||
controller.translation = Some((vel.0 + global_motion) * controller.custom_mass.unwrap_or(1.0) * time.delta_secs());
|
||||
}
|
||||
|
||||
fn keyboard_input(
|
||||
key: Res<ButtonInput<KeyCode>>,
|
||||
player: Single<
|
||||
(
|
||||
&mut PlayerMotion,
|
||||
&mut PlayerVelocity,
|
||||
&MoveSpeed,
|
||||
&JumpSpeed,
|
||||
&Transform,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
) {
|
||||
let (mut motion, mut vel, speed, jump, transform, output) = player.into_inner();
|
||||
let mut move_vec = Vec3::ZERO;
|
||||
|
||||
if key.pressed(KeyCode::KeyW) {
|
||||
move_vec.z = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyS) {
|
||||
move_vec.z = 1.0;
|
||||
}
|
||||
|
||||
if key.pressed(KeyCode::KeyA) {
|
||||
move_vec.x = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyD) {
|
||||
move_vec.x = 1.0;
|
||||
}
|
||||
|
||||
move_vec = move_vec.normalize_or_zero() * speed.0;
|
||||
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
if key.just_pressed(KeyCode::Space) && is_grounded {
|
||||
vel.0 += transform.up() * jump.0;
|
||||
}
|
||||
|
||||
motion.0 = move_vec;
|
||||
|
||||
// transform.rotate_z(angle * time.delta_secs());
|
||||
// controller.up = transform.up().as_vec3();
|
||||
// move_vec += transform.down().as_vec3();
|
||||
// controller.translation = Some(move_vec * time.delta_secs());
|
||||
}
|
||||
|
||||
fn player_look(
|
||||
mut player: Single<&mut Transform, With<Player>>,
|
||||
mut cam_pitch: Single<&mut CameraPitch>,
|
||||
mouse_motion: EventReader<MouseMotion>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let delta = get_mouse_delta(mouse_motion) * -time.delta_secs();
|
||||
let up = player.up();
|
||||
player.rotate_axis(up, delta.x);
|
||||
cam_pitch.0 = (cam_pitch.0 + delta.y).clamp(-FRAC_PI_2 + 0.001, FRAC_PI_2 - 0.001);
|
||||
}
|
||||
|
||||
fn align_with_gravity(
|
||||
player: Single<
|
||||
(
|
||||
&mut Transform,
|
||||
&GravityDirection,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut transform, grav, output) = player.into_inner();
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
|
||||
if !is_grounded {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(grav_dir) = grav.0 else {
|
||||
return;
|
||||
};
|
||||
|
||||
let grav_up = grav_dir * -1.0;
|
||||
|
||||
let desired_rotation = get_alignment_rotation_preserve_twist(transform.rotation, grav_up);
|
||||
transform.rotation = transform.rotation.lerp(desired_rotation, time.delta_secs());
|
||||
}
|
||||
use std::f32::{EPSILON, consts::FRAC_PI_2};
|
||||
|
||||
use bevy::{input::mouse::MouseMotion, prelude::*};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{
|
||||
components::{
|
||||
camera::CameraPitch,
|
||||
player::{GravityDirection, JumpSpeed, MoveSpeed, PlayerDrag, PlayerForce, PlayerMotion, PlayerVelocity},
|
||||
tags::Player,
|
||||
},
|
||||
states::input::PlayerInputSystems,
|
||||
utils::{input::get_mouse_delta, rotation::get_alignment_rotation_preserve_twist},
|
||||
};
|
||||
|
||||
pub struct PlayerPlugin;
|
||||
|
||||
impl Plugin for PlayerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(PreUpdate, (keyboard_input, player_look).in_set(PlayerInputSystems));
|
||||
app.add_systems(Update, (apply_gravity, apply_forces, apply_motion, apply_drag).chain());
|
||||
app.add_systems(Update, align_with_gravity);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_forces(player: Single<(&mut PlayerVelocity, &PlayerForce), With<Player>>, time: Res<Time>) {
|
||||
let (mut vel, force) = player.into_inner();
|
||||
|
||||
vel.0 += force.0 * time.delta_secs();
|
||||
}
|
||||
|
||||
fn apply_gravity(
|
||||
player: Single<
|
||||
(
|
||||
&mut PlayerVelocity,
|
||||
&GravityDirection,
|
||||
&GravityScale,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut vel, dir, scale, output) = player.into_inner();
|
||||
let Some(grav) = dir.0.map(|d| d.as_vec3()) else {
|
||||
return;
|
||||
};
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
if !is_grounded {
|
||||
vel.0 += grav * scale.0 * 9.47 * time.delta_secs();
|
||||
} else {
|
||||
let dot = vel.0.dot(grav);
|
||||
if dot > EPSILON {
|
||||
vel.0 -= dot * grav;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_drag(player: Single<(&mut PlayerVelocity, &PlayerDrag), With<Player>>, time: Res<Time>) {
|
||||
let (mut vel, drag) = player.into_inner();
|
||||
vel.0 *= (1.0 - drag.0 * time.delta_secs()).max(0.0);
|
||||
}
|
||||
|
||||
fn apply_motion(
|
||||
player: Single<
|
||||
(
|
||||
&mut KinematicCharacterController,
|
||||
&Transform,
|
||||
&PlayerVelocity,
|
||||
&PlayerMotion,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut controller, transform, vel, motion) = player.into_inner();
|
||||
// let max_vel = vel.0.clamp_length_max(500.0);
|
||||
let global_motion = transform.rotation * motion.0;
|
||||
controller.translation = Some((vel.0 + global_motion) * controller.custom_mass.unwrap_or(1.0) * time.delta_secs());
|
||||
}
|
||||
|
||||
fn keyboard_input(
|
||||
key: Res<ButtonInput<KeyCode>>,
|
||||
player: Single<
|
||||
(
|
||||
&mut PlayerMotion,
|
||||
&mut PlayerVelocity,
|
||||
&MoveSpeed,
|
||||
&JumpSpeed,
|
||||
&Transform,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
) {
|
||||
let (mut motion, mut vel, speed, jump, transform, output) = player.into_inner();
|
||||
let mut move_vec = Vec3::ZERO;
|
||||
|
||||
if key.pressed(KeyCode::KeyW) {
|
||||
move_vec.z = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyS) {
|
||||
move_vec.z = 1.0;
|
||||
}
|
||||
|
||||
if key.pressed(KeyCode::KeyA) {
|
||||
move_vec.x = -1.0;
|
||||
} else if key.pressed(KeyCode::KeyD) {
|
||||
move_vec.x = 1.0;
|
||||
}
|
||||
|
||||
move_vec = move_vec.normalize_or_zero() * speed.0;
|
||||
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
if key.just_pressed(KeyCode::Space) && is_grounded {
|
||||
vel.0 += transform.up() * jump.0;
|
||||
}
|
||||
|
||||
motion.0 = move_vec;
|
||||
|
||||
// transform.rotate_z(angle * time.delta_secs());
|
||||
// controller.up = transform.up().as_vec3();
|
||||
// move_vec += transform.down().as_vec3();
|
||||
// controller.translation = Some(move_vec * time.delta_secs());
|
||||
}
|
||||
|
||||
fn player_look(
|
||||
mut player: Single<&mut Transform, With<Player>>,
|
||||
mut cam_pitch: Single<&mut CameraPitch>,
|
||||
mouse_motion: EventReader<MouseMotion>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let delta = get_mouse_delta(mouse_motion) * -time.delta_secs();
|
||||
let up = player.up();
|
||||
player.rotate_axis(up, delta.x);
|
||||
cam_pitch.0 = (cam_pitch.0 + delta.y).clamp(-FRAC_PI_2 + 0.001, FRAC_PI_2 - 0.001);
|
||||
}
|
||||
|
||||
fn align_with_gravity(
|
||||
player: Single<
|
||||
(
|
||||
&mut Transform,
|
||||
&GravityDirection,
|
||||
Option<&KinematicCharacterControllerOutput>,
|
||||
),
|
||||
With<Player>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let (mut transform, grav, output) = player.into_inner();
|
||||
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
|
||||
|
||||
if !is_grounded {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(grav_dir) = grav.0 else {
|
||||
return;
|
||||
};
|
||||
|
||||
let grav_up = grav_dir * -1.0;
|
||||
|
||||
let desired_rotation = get_alignment_rotation_preserve_twist(transform.rotation, grav_up);
|
||||
transform.rotation = transform.rotation.lerp(desired_rotation, time.delta_secs());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user