Rewrite and simplify movement, reorder player functions
This commit is contained in:
parent
db8f352517
commit
9875417232
1 changed files with 59 additions and 83 deletions
142
src/player.rs
142
src/player.rs
|
@ -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 {
|
||||
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
|
||||
pitch: f32,
|
||||
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
|
||||
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_FRICTION: f32 = 1.0;
|
||||
const PLAYER_SPEED: f32 = 320.0;
|
||||
const MOUSE_SENSITIVITY: f32 = 6.0;
|
||||
|
||||
impl Player {
|
||||
|
@ -26,11 +40,50 @@ impl Player {
|
|||
Self {
|
||||
pitch: 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 {
|
||||
rotation.mul_vec3(Vec3::unit_z()).normalize()
|
||||
}
|
||||
|
@ -55,57 +108,7 @@ fn movement_axis(input: &Res<Input<KeyCode>>, plus: KeyCode, minus: KeyCode) ->
|
|||
axis
|
||||
}
|
||||
|
||||
fn camera_movement_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(
|
||||
fn player_look_system(
|
||||
time: Res<Time>,
|
||||
mut state: ResMut<State>,
|
||||
mut bodies: ResMut<RigidBodySet>,
|
||||
|
@ -138,30 +141,3 @@ fn mouse_motion_system(
|
|||
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));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue