Rewrite and simplify movement, reorder player functions

This commit is contained in:
Felix Ableitner 2021-01-01 17:40:58 +01:00
parent db8f352517
commit 9875417232

View file

@ -8,17 +8,31 @@ use bevy_rapier3d::{
}, },
}; };
pub struct PlayerPlugin;
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut AppBuilder) {
app
.init_resource::<State>()
.add_system(player_movement_system.system())
.add_system(player_look_system.system())
.add_startup_system(init_player.system());
}
}
#[derive(Default)]
struct State {
mouse_motion_event_reader: EventReader<MouseMotion>,
}
struct Player { struct Player {
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html) /// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
pitch: f32, pitch: f32,
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html) /// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
yaw: f32, yaw: f32,
/// The current velocity of the FlyCamera. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
velocity: Vec3,
} }
const PLAYER_SPEED: f32 = 15.0; const PLAYER_SPEED: f32 = 320.0;
const PLAYER_FRICTION: f32 = 1.0;
const MOUSE_SENSITIVITY: f32 = 6.0; const MOUSE_SENSITIVITY: f32 = 6.0;
impl Player { impl Player {
@ -26,11 +40,50 @@ impl Player {
Self { Self {
pitch: 0.0, pitch: 0.0,
yaw: 0.0, yaw: 0.0,
velocity: Vec3::zero(),
} }
} }
} }
fn init_player(commands: &mut Commands) {
commands
.spawn(Camera3dBundle {
transform: Transform::from_translation(Vec3::new(0.0, 3.0, 3.0)),
..Default::default()
})
.with(Player::create())
.with(
RigidBodyBuilder::new_dynamic()
.translation(0.0, 3.0, 0.0)
.lock_rotations(),
)
.with(ColliderBuilder::cylinder(1.0, 0.5).friction(0.0));
}
fn player_movement_system(
time: Res<Time>,
mut bodies: ResMut<RigidBodySet>,
keyboard_input: Res<Input<KeyCode>>,
mut query: Query<(&mut Transform, &RigidBodyHandleComponent), With<Player>>,
) {
for (transform, handle) in query.iter_mut() {
let body: &mut RigidBody = bodies.get_mut(handle.handle()).unwrap();
let axis_straight = movement_axis(&keyboard_input, KeyCode::D, KeyCode::A);
let axis_strafe = movement_axis(&keyboard_input, KeyCode::S, KeyCode::W);
let rotation = transform.rotation;
let mut speed_2d: Vec3 =
(strafe_vector(&rotation) * axis_straight) + (forward_vector(&rotation) * axis_strafe);
if speed_2d.length() != 0.0 {
speed_2d = speed_2d.normalize() * PLAYER_SPEED;
}
let velocity_2d = speed_2d * time.delta_seconds();
let velocity_3d = Matrix3x1::new(velocity_2d.x, body.linvel().y, velocity_2d.z);
body.set_linvel(velocity_3d, true);
}
}
fn forward_vector(rotation: &Quat) -> Vec3 { fn forward_vector(rotation: &Quat) -> Vec3 {
rotation.mul_vec3(Vec3::unit_z()).normalize() rotation.mul_vec3(Vec3::unit_z()).normalize()
} }
@ -55,57 +108,7 @@ fn movement_axis(input: &Res<Input<KeyCode>>, plus: KeyCode, minus: KeyCode) ->
axis axis
} }
fn camera_movement_system( fn player_look_system(
time: Res<Time>,
mut bodies: ResMut<RigidBodySet>,
keyboard_input: Res<Input<KeyCode>>,
mut query: Query<(&mut Player, &mut Transform, &RigidBodyHandleComponent)>,
) {
for (mut player, transform, handle) in query.iter_mut() {
let body: &mut RigidBody = bodies.get_mut(handle.handle()).unwrap();
let (axis_h, axis_v, axis_float) = (
movement_axis(&keyboard_input, KeyCode::D, KeyCode::A),
movement_axis(&keyboard_input, KeyCode::S, KeyCode::W),
movement_axis(&keyboard_input, KeyCode::Space, KeyCode::LControl),
);
let rotation = transform.rotation;
let accel: Vec3 = (strafe_vector(&rotation) * axis_h)
+ (forward_vector(&rotation) * axis_v)
+ (Vec3::unit_y() * axis_float);
let accel: Vec3 = if accel.length() != 0.0 {
accel.normalize() * PLAYER_SPEED
} else {
Vec3::zero()
};
let friction: Vec3 = if player.velocity.length() != 0.0 {
player.velocity.normalize() * -1.0 * PLAYER_FRICTION
} else {
Vec3::zero()
};
player.velocity += accel * time.delta_seconds();
let vel = Matrix3x1::new(player.velocity.x, body.linvel().y, player.velocity.z);
body.set_linvel(vel, true);
let delta_friction = friction * time.delta_seconds();
player.velocity = if (player.velocity + delta_friction).signum() != player.velocity.signum() {
Vec3::zero()
} else {
player.velocity + delta_friction
};
}
}
#[derive(Default)]
struct State {
mouse_motion_event_reader: EventReader<MouseMotion>,
}
fn mouse_motion_system(
time: Res<Time>, time: Res<Time>,
mut state: ResMut<State>, mut state: ResMut<State>,
mut bodies: ResMut<RigidBodySet>, mut bodies: ResMut<RigidBodySet>,
@ -138,30 +141,3 @@ fn mouse_motion_system(
body.set_angvel(Matrix3x1::new(pitch_radians, yaw_radians, 0.), true); body.set_angvel(Matrix3x1::new(pitch_radians, yaw_radians, 0.), true);
} }
} }
pub struct PlayerPlugin;
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut AppBuilder) {
app
.init_resource::<State>()
.add_system(camera_movement_system.system())
.add_system(mouse_motion_system.system())
.add_startup_system(init_player.system());
}
}
fn init_player(commands: &mut Commands) {
commands
.spawn(Camera3dBundle {
transform: Transform::from_translation(Vec3::new(0.0, 3.0, 3.0)),
..Default::default()
})
.with(Player::create())
.with(
RigidBodyBuilder::new_dynamic()
.translation(0.0, 3.0, 0.0)
.lock_rotations(),
)
.with(ColliderBuilder::cylinder(1.0, 0.5).friction(0.0));
}