implemented air control, made going up slope more difficult depending on angle

This commit is contained in:
NIMFER 2024-03-23 02:40:33 +01:00
parent f5ca4128e3
commit 53de23e58a

View file

@ -45,6 +45,7 @@ pub struct Grounded;
#[derive(Component)]
pub struct CharacterController{
pub movement_acceleration: Scalar,
pub air_control_factor: Scalar,
pub movement_dampening_factor: Scalar,
pub jump_impulse: Scalar,
pub max_slope_angle: Scalar,
@ -54,6 +55,7 @@ impl Default for CharacterController {
fn default() -> Self {
CharacterController{
movement_acceleration: 20.0,
air_control_factor: 0.5,
movement_dampening_factor: 0.95,
jump_impulse: 4.0,
max_slope_angle: (30.0 as Scalar).to_radians(),
@ -145,30 +147,35 @@ pub fn keyboard_input(mut movement_event_writer: EventWriter<MovementAction>, ke
}
}
pub fn move_character(time: Res<Time>, mut movement_event_reader: EventReader<MovementAction>,
mut qeury: Query<(&mut LinearVelocity, &CharacterController, Has<Grounded>, &Rotation, &ShapeHits)>
){
pub fn move_character(
time: Res<Time>,
mut movement_event_reader: EventReader<MovementAction>,
mut query: Query<(&mut LinearVelocity, &CharacterController, Has<Grounded>, &Rotation, &ShapeHits)>,
) {
let delta_time = time.delta_seconds_f64().adjust_precision();
for event in movement_event_reader.read() {
for (mut velocity, character_controller, is_grounded, rotation, shape_hits) in &mut qeury{
match event{
for (mut velocity, character_controller, is_grounded, rotation, shape_hits) in &mut query {
match event {
MovementAction::Move(direction) => {
if is_grounded {
velocity.x += direction.x * character_controller.movement_acceleration * delta_time;
velocity.z -= direction.y * character_controller.movement_acceleration * delta_time;
}
else {
shape_hits.iter().any(|hit| {
let mut slope_factor = 1.0;
for hit in shape_hits.iter() {
let angle = rotation.rotate(-hit.normal2).angle_between(Vector::Y).abs();
velocity.x += direction.x * (character_controller.movement_acceleration - (character_controller.movement_acceleration / angle)) * delta_time;
velocity.z -= direction.y * (character_controller.movement_acceleration - (character_controller.movement_acceleration / angle)) * delta_time;
angle <= character_controller.max_slope_angle
});
if angle <= character_controller.max_slope_angle {
slope_factor *= (angle / character_controller.max_slope_angle).cos();
} else {
velocity.x = 0.0;
velocity.z = 0.0;
}
}
velocity.x += direction.x * character_controller.movement_acceleration * delta_time * slope_factor;
velocity.z -= direction.y * character_controller.movement_acceleration * delta_time * slope_factor;
} else {
velocity.x += direction.x * character_controller.movement_acceleration * delta_time * character_controller.air_control_factor;
velocity.z -= direction.y * character_controller.movement_acceleration * delta_time * character_controller.air_control_factor;
}
}
},
MovementAction::Jump => {
if is_grounded {
velocity.y = character_controller.jump_impulse;
@ -176,11 +183,11 @@ pub fn move_character(time: Res<Time>, mut movement_event_reader: EventReader<Mo
}
}
}
}
}
pub fn dampen_movement(mut qeury: Query<(&mut LinearVelocity, &CharacterController)>){
for (mut velocity, character_controller) in &mut qeury {
// We could use `LinearDamping`, but we don't want to dampen movement along the Y axis