bevy_fpc_core/
linear.rs

1//! Linear movement related module
2
3use crate::{
4    config::{FpcConfiguration, KeyboardLinearInputs},
5    Player,
6};
7use bevy::prelude::*;
8use bevy_rapier3d::{na::clamp, prelude::*};
9
10/// Default value for the `WalkSpeed` component
11const DEFAULT_WALK_SPEED: f32 = 2.;
12
13/// Component used to mutate speed of controller horizontal translations when walking.
14/// Contain one value by which the linear velocity will be multiplied.
15///
16/// Default value is `DEFAULT_WALK_SPEED`.
17#[derive(Component)]
18pub struct WalkSpeed(pub f32);
19impl Default for WalkSpeed {
20    fn default() -> Self {
21        Self(DEFAULT_WALK_SPEED)
22    }
23}
24
25#[derive(Component)]
26pub struct Gravity(pub f32);
27
28/// Enable linear movements from player inputs.
29///
30/// Keyboard inputs are configurable with `FpcConfiguration.keyboard_linear_inputs`.
31/// Internally using _Rapier_ `KinematicCharacterController`.
32pub fn handle_movements(
33    mut query: Query<
34        (
35            &mut KinematicCharacterController,
36            &mut RigidBody,
37            &Transform,
38            &WalkSpeed,
39            &mut Gravity,
40            &KinematicCharacterControllerOutput,
41        ),
42        With<Player>,
43    >,
44    fpc_conf: Res<FpcConfiguration>,
45    inputs: Res<ButtonInput<KeyCode>>,
46    time: Res<Time>,
47) {
48    query.iter_mut().for_each(
49        |(mut controller, _ridgidbody, transform, walk_speed, mut gravity, controller_output)| {
50            /* if !*ridgidbody.is_ccd_enabled(){
51                *ridgidbody.enable_ccd(true);
52            } */
53
54            let KeyboardLinearInputs {
55                forward,
56                right,
57                back,
58                left,
59            } = fpc_conf.keyboard_linear_inputs;
60            let mut linear_velocity = Vec3::ZERO;
61            if inputs.pressed(forward) {
62                linear_velocity += transform.forward().normalize();
63            }
64            if inputs.pressed(back) {
65                linear_velocity += transform.back().normalize();
66            }
67            if inputs.pressed(right) {
68                linear_velocity += transform.right().normalize();
69            }
70            if inputs.pressed(left) {
71                linear_velocity += transform.left().normalize();
72            }
73
74            if linear_velocity.length() > 0. {
75                linear_velocity = linear_velocity.normalize();
76                linear_velocity *= time.delta_seconds();
77                linear_velocity *= walk_speed.0;
78            }
79
80            if controller_output.grounded {
81                *gravity = Gravity(0.0);
82            }
83
84            if inputs.just_pressed(KeyCode::Space) {
85                *gravity = Gravity(-10.0 * time.delta_seconds());
86            }
87
88            gravity.0 += clamp((4.9 * time.delta_seconds()).powf(2.0), 0.0, 50.0);
89
90            linear_velocity -= Vec3::new(0.0, gravity.0, 0.0);
91
92            controller.translation = Some(linear_velocity);
93        },
94    );
95}