remove damping
* try fix sliding upwards gaining speed
This commit is contained in:
@@ -1,32 +1,21 @@
|
||||
use super::{ControllerSet, Controls, collisions::kinematic_controller_collisions};
|
||||
use crate::{GameState, player::PlayerRig};
|
||||
use avian3d::{math::*, prelude::*};
|
||||
use bevy::{ecs::query::Has, prelude::*};
|
||||
|
||||
use crate::{GameState, player::PlayerRig};
|
||||
|
||||
use super::{ControllerSet, Controls, collisions::kinematic_controller_collisions};
|
||||
|
||||
pub struct CharacterControllerPlugin;
|
||||
|
||||
impl Plugin for CharacterControllerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<PlayerMovement>();
|
||||
app.init_resource::<MovementSettings>();
|
||||
app.register_type::<MovementSettings>();
|
||||
app.register_type::<MovementDampingFactor>();
|
||||
|
||||
app.register_type::<JumpImpulse>();
|
||||
app.register_type::<ControllerGravity>();
|
||||
app.register_type::<MovementAcceleration>();
|
||||
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
set_movement_flag,
|
||||
brake_on_release,
|
||||
update_grounded,
|
||||
apply_gravity,
|
||||
movement,
|
||||
apply_movement_damping,
|
||||
)
|
||||
(set_movement_flag, update_grounded, apply_gravity, movement)
|
||||
.chain()
|
||||
.in_set(ControllerSet::ApplyControls)
|
||||
.run_if(in_state(GameState::Playing)),
|
||||
@@ -56,35 +45,11 @@ pub struct PlayerMovement {
|
||||
pub any_direction: bool,
|
||||
}
|
||||
|
||||
#[derive(Resource, Reflect)]
|
||||
#[reflect(Resource)]
|
||||
struct MovementSettings {
|
||||
damping_normal: f32,
|
||||
damping_brake: f32,
|
||||
damping_brake_air: f32,
|
||||
}
|
||||
|
||||
// todo some duplicate with player.rs settings
|
||||
impl Default for MovementSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
damping_normal: 1.0,
|
||||
damping_brake: 30.0,
|
||||
damping_brake_air: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The acceleration used for character movement.
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct MovementAcceleration(Scalar);
|
||||
|
||||
/// The damping factor used for slowing down movement.
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct MovementDampingFactor(Scalar);
|
||||
|
||||
/// The strength of a jump.
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
@@ -118,35 +83,22 @@ pub struct CharacterControllerBundle {
|
||||
#[derive(Bundle)]
|
||||
pub struct MovementBundle {
|
||||
acceleration: MovementAcceleration,
|
||||
damping: MovementDampingFactor,
|
||||
jump_impulse: JumpImpulse,
|
||||
max_slope_angle: MaxSlopeAngle,
|
||||
}
|
||||
|
||||
impl MovementBundle {
|
||||
pub const fn new(
|
||||
acceleration: Scalar,
|
||||
damping: Scalar,
|
||||
jump_impulse: Scalar,
|
||||
max_slope_angle: Scalar,
|
||||
) -> Self {
|
||||
pub const fn new(acceleration: Scalar, jump_impulse: Scalar, max_slope_angle: Scalar) -> Self {
|
||||
Self {
|
||||
acceleration: MovementAcceleration(acceleration),
|
||||
damping: MovementDampingFactor(damping),
|
||||
jump_impulse: JumpImpulse(jump_impulse),
|
||||
max_slope_angle: MaxSlopeAngle(max_slope_angle),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MovementBundle {
|
||||
fn default() -> Self {
|
||||
Self::new(30.0, 0.9, 7.0, PI * 0.45)
|
||||
}
|
||||
}
|
||||
|
||||
impl CharacterControllerBundle {
|
||||
pub fn new(collider: Collider, gravity: Vector) -> Self {
|
||||
pub fn new(collider: Collider, gravity: Vector, movement: MovementBundle) -> Self {
|
||||
// Create shape caster as a slightly smaller version of collider
|
||||
let mut caster_shape = collider.clone();
|
||||
caster_shape.set_scale(Vector::ONE * 0.98, 10);
|
||||
@@ -163,39 +115,7 @@ impl CharacterControllerBundle {
|
||||
)
|
||||
.with_max_distance(0.2),
|
||||
gravity: ControllerGravity(gravity),
|
||||
movement: MovementBundle::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_movement(
|
||||
mut self,
|
||||
acceleration: Scalar,
|
||||
damping: Scalar,
|
||||
jump_impulse: Scalar,
|
||||
max_slope_angle: Scalar,
|
||||
) -> Self {
|
||||
self.movement = MovementBundle::new(acceleration, damping, jump_impulse, max_slope_angle);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply extra friction when no movement input is given
|
||||
/// In the original you stop instantly in this case
|
||||
fn brake_on_release(
|
||||
player_movement: Res<PlayerMovement>,
|
||||
movement_settings: Res<MovementSettings>,
|
||||
mut damping_q: Query<(Entity, &mut MovementDampingFactor)>,
|
||||
grounded_q: Query<&Grounded>,
|
||||
) {
|
||||
for (entity, mut damping) in &mut damping_q {
|
||||
let is_grounded = grounded_q.get(entity).is_ok();
|
||||
|
||||
if !player_movement.any_direction && is_grounded {
|
||||
damping.0 = movement_settings.damping_brake;
|
||||
} else if !player_movement.any_direction && !is_grounded {
|
||||
damping.0 = movement_settings.damping_brake_air;
|
||||
} else {
|
||||
damping.0 = movement_settings.damping_normal;
|
||||
movement,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,8 +140,10 @@ fn update_grounded(
|
||||
});
|
||||
|
||||
if is_grounded {
|
||||
info!("grounded");
|
||||
commands.entity(entity).insert(Grounded);
|
||||
} else {
|
||||
info!("not grounded");
|
||||
commands.entity(entity).remove::<Grounded>();
|
||||
}
|
||||
}
|
||||
@@ -256,19 +178,22 @@ fn movement(
|
||||
Has<Grounded>,
|
||||
)>,
|
||||
rig_transform_q: Option<Single<&GlobalTransform, With<PlayerRig>>>,
|
||||
mut jump_used: Local<bool>,
|
||||
) {
|
||||
let delta_time = time.delta_secs();
|
||||
|
||||
let mut direction = controls.keyboard_state.move_dir;
|
||||
|
||||
let mut jump_requested = controls.keyboard_state.jump;
|
||||
|
||||
if let Some(gamepad) = controls.gamepad_state {
|
||||
direction += gamepad.move_dir;
|
||||
direction = direction.normalize_or_zero();
|
||||
|
||||
jump_requested |= gamepad.jump;
|
||||
}
|
||||
|
||||
direction = direction.normalize_or_zero();
|
||||
|
||||
for (movement_acceleration, jump_impulse, mut linear_velocity, is_grounded) in &mut controllers
|
||||
{
|
||||
let mut direction = direction.extend(0.0).xzy();
|
||||
@@ -278,11 +203,22 @@ fn movement(
|
||||
(rig_transform.forward() * direction.z) + (rig_transform.right() * direction.x);
|
||||
}
|
||||
|
||||
linear_velocity.x -= direction.x * movement_acceleration.0 * delta_time;
|
||||
linear_velocity.z -= direction.z * movement_acceleration.0 * delta_time;
|
||||
linear_velocity.x = -direction.x * movement_acceleration.0 * delta_time;
|
||||
linear_velocity.z = -direction.z * movement_acceleration.0 * delta_time;
|
||||
|
||||
if is_grounded && jump_requested {
|
||||
if is_grounded && jump_requested && !*jump_used {
|
||||
linear_velocity.y = jump_impulse.0;
|
||||
info!("jump");
|
||||
*jump_used = true;
|
||||
}
|
||||
|
||||
if !controls.keyboard_state.jump
|
||||
&& !controls
|
||||
.gamepad_state
|
||||
.map(|state| state.jump)
|
||||
.unwrap_or_default()
|
||||
{
|
||||
*jump_used = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,25 +226,13 @@ fn movement(
|
||||
/// Applies [`ControllerGravity`] to character controllers.
|
||||
fn apply_gravity(
|
||||
time: Res<Time>,
|
||||
mut controllers: Query<(&ControllerGravity, &mut LinearVelocity)>,
|
||||
mut controllers: Query<(&ControllerGravity, &mut LinearVelocity, Option<&Grounded>)>,
|
||||
) {
|
||||
let delta_time = time.delta_secs();
|
||||
|
||||
for (gravity, mut linear_velocity) in &mut controllers {
|
||||
linear_velocity.0 += gravity.0 * delta_time;
|
||||
}
|
||||
}
|
||||
|
||||
/// Slows down movement in the XZ plane.
|
||||
fn apply_movement_damping(
|
||||
time: Res<Time>,
|
||||
mut query: Query<(&MovementDampingFactor, &mut LinearVelocity)>,
|
||||
) {
|
||||
let delta_time = time.delta_secs();
|
||||
|
||||
for (damping_factor, mut linear_velocity) in &mut query {
|
||||
// We could use `LinearDamping`, but we don't want to dampen movement along the Y axis
|
||||
linear_velocity.x *= 1.0 - damping_factor.0 * delta_time;
|
||||
linear_velocity.z *= 1.0 - damping_factor.0 * delta_time;
|
||||
for (gravity, mut linear_velocity, grounded) in &mut controllers {
|
||||
if grounded.is_none() {
|
||||
linear_velocity.0 += gravity.0 * delta_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user