use bevy::prelude::*; use shared::{ GameState, control::{ControllerSet, Inputs, LookDirMovement}, player::{LocalPlayer, PlayerBodyMesh}, }; use std::f32::consts::PI; pub fn plugin(app: &mut App) { app.add_systems( FixedUpdate, rotate_rig .before(shared::control::controller_flying::apply_controls) .in_set(ControllerSet::ApplyControlsFly) .run_if(in_state(GameState::Playing)), ); } fn rotate_rig( inputs: Single<&Inputs, With>, look_dir: Res, local_player: Single<&Children, With>, mut player_mesh: Query<&mut Transform, With>, ) { if inputs.view_mode { return; } local_player.iter().find(|&child| { if let Ok(mut rig_transform) = player_mesh.get_mut(child) { let look_dir = look_dir.0; // 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; true } else { false } }); }