diff --git a/src/camera.rs b/src/camera.rs index e3cbbe5..3cf6f6d 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -2,8 +2,10 @@ use avian3d::prelude::*; use bevy::prelude::*; use crate::{ - GameState, control::Controls, control::controller_common::PlayerMovement, - loading_assets::UIAssets, physics_layers::GameLayer, + GameState, + control::{ControlState, controller_common::PlayerMovement}, + loading_assets::UIAssets, + physics_layers::GameLayer, }; #[derive(Component, Reflect, Debug)] @@ -50,14 +52,7 @@ pub fn plugin(app: &mut App) { app.add_systems(OnEnter(GameState::Playing), startup); app.add_systems( Update, - ( - update, - update_ui, - update_look_around, - rotate_view_keyboard, - rotate_view_gamepad, - ) - .run_if(in_state(GameState::Playing)), + (update, update_ui, update_look_around, rotate_view).run_if(in_state(GameState::Playing)), ); } @@ -69,9 +64,8 @@ fn startup(mut commands: Commands) { )); } -fn update_look_around(controls: Res, mut cam_state: ResMut) { - let look_around = - controls.keyboard_state.view_mode || controls.gamepad_state.is_some_and(|g| g.view_mode); +fn update_look_around(controls: Res, mut cam_state: ResMut) { + let look_around = controls.view_mode; if look_around != cam_state.look_around { cam_state.look_around = look_around; @@ -159,8 +153,8 @@ fn update( *cam_transform = Transform::from_translation(cam_pos).looking_at(target, Vec3::Y); } -fn rotate_view_keyboard( - mut controls: ResMut, +fn rotate_view( + controls: Res, mut cam: Query<&mut CameraRotationInput>, movement: Res, ) { @@ -168,7 +162,7 @@ fn rotate_view_keyboard( return; }; - if !controls.keyboard_state.view_mode { + if !controls.view_mode { if movement.any_direction { cam.x = 0.; } @@ -176,31 +170,5 @@ fn rotate_view_keyboard( return; } - cam.x += controls.keyboard_state.look_dir.x * -0.001; - cam.y += controls.keyboard_state.look_dir.y * -0.001; - - controls.keyboard_state.look_dir = Vec2::ZERO; -} - -fn rotate_view_gamepad( - controls: Res, - mut cam: Query<&mut CameraRotationInput>, - movement: Res, -) { - let Ok(mut cam) = cam.get_single_mut() else { - return; - }; - - let Some(gamepad) = controls.gamepad_state else { - return; - }; - - if !gamepad.view_mode { - if movement.any_direction { - cam.x = 0.; - } - } else { - cam.x += gamepad.look_dir.x * -0.001; - cam.y += gamepad.look_dir.y * -0.001; - } + cam.0 += controls.look_dir * -0.001; } diff --git a/src/control/controller_flying.rs b/src/control/controller_flying.rs index 67ae792..80e4292 100644 --- a/src/control/controller_flying.rs +++ b/src/control/controller_flying.rs @@ -6,7 +6,7 @@ use bevy::prelude::*; use crate::player::PlayerBodyMesh; use super::{ - ControllerSet, Controls, + ControlState, ControllerSet, Controls, controller_common::{JumpImpulse, MovementDampingFactor, MovementSpeed, PlayerMovement}, }; @@ -35,23 +35,13 @@ fn set_movement_flag(mut player_movement: ResMut) { fn rotate_rig( mut rig_transform_q: Option>>, - mut controls: ResMut, + controls: Res, ) { - if controls.keyboard_state.view_mode { + if controls.view_mode { return; } - let look_dir; - - if let Some(gamepad) = controls.gamepad_state { - look_dir = gamepad.look_dir + controls.keyboard_state.look_dir; - - if gamepad.view_mode { - return; - } - } else { - look_dir = controls.keyboard_state.look_dir; - }; + let look_dir = controls.look_dir; if let Some(ref mut rig_transform) = rig_transform_q { // todo: Make consistent with the running controller @@ -74,8 +64,6 @@ fn rotate_rig( // let clamped_rotation = rig_transform.rotation.rotate_towards(target_rotation, 0.01); // rig_transform.rotation = clamped_rotation; } - - controls.keyboard_state.look_dir = Vec2::ZERO; } /// Responds to [`MovementAction`] events and moves character controllers accordingly. diff --git a/src/control/controller_running.rs b/src/control/controller_running.rs index 6751a8f..9ce8d0c 100644 --- a/src/control/controller_running.rs +++ b/src/control/controller_running.rs @@ -1,4 +1,4 @@ -use super::{ControllerSet, Controls, controller_common::MovementSpeedFactor}; +use super::{ControlState, ControllerSet, Controls, controller_common::MovementSpeedFactor}; use crate::{GameState, player::PlayerBodyMesh}; use avian3d::{math::*, prelude::*}; use bevy::{ecs::query::Has, prelude::*}; @@ -19,8 +19,7 @@ impl Plugin for CharacterControllerPlugin { set_movement_flag, update_grounded, apply_gravity, - rotate_view_keyboard, - rotate_view_gamepad, // todo consider merging these two + rotate_view, movement, ) .chain() @@ -77,38 +76,19 @@ fn set_movement_flag(mut player_movement: ResMut, controls: Res< } } -fn rotate_view_gamepad( - controls: Res, +fn rotate_view( + controls: Res, mut player: Query<&mut Transform, With>, ) { - let Some(gamepad) = controls.gamepad_state else { - return; - }; - - if gamepad.view_mode { + if controls.view_mode { return; } for mut tr in &mut player { - tr.rotate_y(gamepad.look_dir.x * -0.001); + tr.rotate_y(controls.look_dir.x * -0.001); } } -fn rotate_view_keyboard( - mut controls: ResMut, - mut player: Query<&mut Transform, With>, -) { - if controls.keyboard_state.view_mode { - return; - } - - for mut tr in &mut player { - tr.rotate_y(controls.keyboard_state.look_dir.x * -0.001); - } - - controls.keyboard_state.look_dir = Vec2::ZERO; -} - /// Responds to [`MovementAction`] events and moves character controllers accordingly. fn movement( controls: Res, diff --git a/src/control/controls.rs b/src/control/controls.rs index 0502dda..c925369 100644 --- a/src/control/controls.rs +++ b/src/control/controls.rs @@ -26,12 +26,30 @@ pub fn plugin(app: &mut App) { mouse_rotate, mouse_click.run_if(on_event::), gamepad_connections.run_if(on_event::), + combine_controls, ) + .chain() .in_set(ControllerSet::CollectInputs) .run_if(in_state(GameState::Playing)), ); } +fn combine_controls(controls: Res, mut combined_controls: ResMut) { + let keyboard = controls.keyboard_state; + + if let Some(gamepad) = controls.gamepad_state { + combined_controls.look_dir = gamepad.look_dir + keyboard.look_dir; + combined_controls.move_dir = gamepad.move_dir + keyboard.move_dir; + combined_controls.jump = gamepad.jump | keyboard.jump; + combined_controls.view_mode = gamepad.view_mode | keyboard.view_mode; + } else { + combined_controls.look_dir = keyboard.look_dir; + combined_controls.move_dir = keyboard.move_dir; + combined_controls.jump = keyboard.jump; + combined_controls.view_mode = keyboard.view_mode; + }; +} + /// Applies a square deadzone to a Vec2 fn deadzone_square(v: Vec2, min: f32) -> Vec2 { Vec2::new( @@ -125,6 +143,8 @@ fn gamepad_controls( } fn mouse_rotate(mut mouse: EventReader, mut controls: ResMut) { + controls.keyboard_state.look_dir = Vec2::ZERO; + for ev in mouse.read() { controls.keyboard_state.look_dir += ev.delta; } diff --git a/src/control/mod.rs b/src/control/mod.rs index d6b7c50..a37183f 100644 --- a/src/control/mod.rs +++ b/src/control/mod.rs @@ -31,9 +31,9 @@ pub struct ControlState { } #[derive(Resource, Debug, Default)] -pub struct Controls { - pub keyboard_state: ControlState, - pub gamepad_state: Option, +struct Controls { + keyboard_state: ControlState, + gamepad_state: Option, } #[derive(Event)] @@ -44,6 +44,7 @@ pub struct SelectedController(ControllerSet); pub fn plugin(app: &mut App) { app.init_resource::(); + app.init_resource::(); app.add_plugins(controls::plugin); app.add_plugins(controller_common::plugin);