64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use super::{ControlState, ControllerSet};
|
|
use crate::{GameState, control::controller_common::MovementSpeedFactor, player::PlayerBodyMesh};
|
|
use bevy::prelude::*;
|
|
use happy_feet::prelude::MoveInput;
|
|
use std::f32::consts::PI;
|
|
|
|
pub struct CharacterControllerPlugin;
|
|
|
|
impl Plugin for CharacterControllerPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_systems(
|
|
PreUpdate,
|
|
(rotate_rig, apply_controls)
|
|
.chain()
|
|
.in_set(ControllerSet::ApplyControlsFly)
|
|
.run_if(in_state(GameState::Playing)),
|
|
);
|
|
}
|
|
}
|
|
|
|
fn rotate_rig(
|
|
mut rig_transform_q: Option<Single<&mut Transform, With<PlayerBodyMesh>>>,
|
|
controls: Res<ControlState>,
|
|
) {
|
|
if controls.view_mode {
|
|
return;
|
|
}
|
|
|
|
let look_dir = controls.look_dir;
|
|
|
|
if let Some(ref mut rig_transform) = rig_transform_q {
|
|
// todo: Make consistent with the running controller
|
|
let sensitivity = 0.001;
|
|
let max_pitch = 35.0 * PI / 180.0;
|
|
let min_pitch = -25.0 * PI / 180.0;
|
|
|
|
rig_transform.rotate_y(look_dir.x * -sensitivity);
|
|
|
|
let euler_rot = rig_transform.rotation.to_euler(EulerRot::YXZ);
|
|
let yaw = euler_rot.0;
|
|
let pitch = euler_rot.1 + look_dir.y * sensitivity;
|
|
|
|
let pitch_clamped = pitch.clamp(min_pitch, max_pitch);
|
|
rig_transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch_clamped, 0.0);
|
|
|
|
// The following can be used to limit the amount of rotation per frame
|
|
// let target_rotation = rig_transform.rotation
|
|
// * Quat::from_rotation_x(controls.keyboard_state.look_dir.y * sensitivity);
|
|
// let clamped_rotation = rig_transform.rotation.rotate_towards(target_rotation, 0.01);
|
|
// rig_transform.rotation = clamped_rotation;
|
|
}
|
|
}
|
|
|
|
fn apply_controls(
|
|
mut character: Query<(&mut MoveInput, &MovementSpeedFactor)>,
|
|
rig_transform_q: Option<Single<&GlobalTransform, With<PlayerBodyMesh>>>,
|
|
) {
|
|
let (mut char_input, factor) = character.single_mut().unwrap();
|
|
|
|
if let Some(ref rig_transform) = rig_transform_q {
|
|
char_input.set(-*rig_transform.forward() * factor.0);
|
|
}
|
|
}
|