Simplify working with controls (#27)

This commit is contained in:
GitGhillie
2025-04-13 21:07:11 +04:00
committed by GitHub
parent 615c55e9ca
commit ca9211d0d1
5 changed files with 45 additions and 88 deletions

View File

@@ -2,8 +2,10 @@ use avian3d::prelude::*;
use bevy::prelude::*; use bevy::prelude::*;
use crate::{ use crate::{
GameState, control::Controls, control::controller_common::PlayerMovement, GameState,
loading_assets::UIAssets, physics_layers::GameLayer, control::{ControlState, controller_common::PlayerMovement},
loading_assets::UIAssets,
physics_layers::GameLayer,
}; };
#[derive(Component, Reflect, Debug)] #[derive(Component, Reflect, Debug)]
@@ -50,14 +52,7 @@ pub fn plugin(app: &mut App) {
app.add_systems(OnEnter(GameState::Playing), startup); app.add_systems(OnEnter(GameState::Playing), startup);
app.add_systems( app.add_systems(
Update, Update,
( (update, update_ui, update_look_around, rotate_view).run_if(in_state(GameState::Playing)),
update,
update_ui,
update_look_around,
rotate_view_keyboard,
rotate_view_gamepad,
)
.run_if(in_state(GameState::Playing)),
); );
} }
@@ -69,9 +64,8 @@ fn startup(mut commands: Commands) {
)); ));
} }
fn update_look_around(controls: Res<Controls>, mut cam_state: ResMut<CameraState>) { fn update_look_around(controls: Res<ControlState>, mut cam_state: ResMut<CameraState>) {
let look_around = let look_around = controls.view_mode;
controls.keyboard_state.view_mode || controls.gamepad_state.is_some_and(|g| g.view_mode);
if look_around != cam_state.look_around { if look_around != cam_state.look_around {
cam_state.look_around = 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); *cam_transform = Transform::from_translation(cam_pos).looking_at(target, Vec3::Y);
} }
fn rotate_view_keyboard( fn rotate_view(
mut controls: ResMut<Controls>, controls: Res<ControlState>,
mut cam: Query<&mut CameraRotationInput>, mut cam: Query<&mut CameraRotationInput>,
movement: Res<PlayerMovement>, movement: Res<PlayerMovement>,
) { ) {
@@ -168,7 +162,7 @@ fn rotate_view_keyboard(
return; return;
}; };
if !controls.keyboard_state.view_mode { if !controls.view_mode {
if movement.any_direction { if movement.any_direction {
cam.x = 0.; cam.x = 0.;
} }
@@ -176,31 +170,5 @@ fn rotate_view_keyboard(
return; return;
} }
cam.x += controls.keyboard_state.look_dir.x * -0.001; cam.0 += controls.look_dir * -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<Controls>,
mut cam: Query<&mut CameraRotationInput>,
movement: Res<PlayerMovement>,
) {
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;
}
} }

View File

@@ -6,7 +6,7 @@ use bevy::prelude::*;
use crate::player::PlayerBodyMesh; use crate::player::PlayerBodyMesh;
use super::{ use super::{
ControllerSet, Controls, ControlState, ControllerSet, Controls,
controller_common::{JumpImpulse, MovementDampingFactor, MovementSpeed, PlayerMovement}, controller_common::{JumpImpulse, MovementDampingFactor, MovementSpeed, PlayerMovement},
}; };
@@ -35,23 +35,13 @@ fn set_movement_flag(mut player_movement: ResMut<PlayerMovement>) {
fn rotate_rig( fn rotate_rig(
mut rig_transform_q: Option<Single<&mut Transform, With<PlayerBodyMesh>>>, mut rig_transform_q: Option<Single<&mut Transform, With<PlayerBodyMesh>>>,
mut controls: ResMut<Controls>, controls: Res<ControlState>,
) { ) {
if controls.keyboard_state.view_mode { if controls.view_mode {
return; return;
} }
let look_dir; let look_dir = controls.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;
};
if let Some(ref mut rig_transform) = rig_transform_q { if let Some(ref mut rig_transform) = rig_transform_q {
// todo: Make consistent with the running controller // 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); // let clamped_rotation = rig_transform.rotation.rotate_towards(target_rotation, 0.01);
// rig_transform.rotation = clamped_rotation; // rig_transform.rotation = clamped_rotation;
} }
controls.keyboard_state.look_dir = Vec2::ZERO;
} }
/// Responds to [`MovementAction`] events and moves character controllers accordingly. /// Responds to [`MovementAction`] events and moves character controllers accordingly.

View File

@@ -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 crate::{GameState, player::PlayerBodyMesh};
use avian3d::{math::*, prelude::*}; use avian3d::{math::*, prelude::*};
use bevy::{ecs::query::Has, prelude::*}; use bevy::{ecs::query::Has, prelude::*};
@@ -19,8 +19,7 @@ impl Plugin for CharacterControllerPlugin {
set_movement_flag, set_movement_flag,
update_grounded, update_grounded,
apply_gravity, apply_gravity,
rotate_view_keyboard, rotate_view,
rotate_view_gamepad, // todo consider merging these two
movement, movement,
) )
.chain() .chain()
@@ -77,38 +76,19 @@ fn set_movement_flag(mut player_movement: ResMut<PlayerMovement>, controls: Res<
} }
} }
fn rotate_view_gamepad( fn rotate_view(
controls: Res<Controls>, controls: Res<ControlState>,
mut player: Query<&mut Transform, With<PlayerBodyMesh>>, mut player: Query<&mut Transform, With<PlayerBodyMesh>>,
) { ) {
let Some(gamepad) = controls.gamepad_state else { if controls.view_mode {
return;
};
if gamepad.view_mode {
return; return;
} }
for mut tr in &mut player { 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<Controls>,
mut player: Query<&mut Transform, With<PlayerBodyMesh>>,
) {
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. /// Responds to [`MovementAction`] events and moves character controllers accordingly.
fn movement( fn movement(
controls: Res<Controls>, controls: Res<Controls>,

View File

@@ -26,12 +26,30 @@ pub fn plugin(app: &mut App) {
mouse_rotate, mouse_rotate,
mouse_click.run_if(on_event::<MouseButtonInput>), mouse_click.run_if(on_event::<MouseButtonInput>),
gamepad_connections.run_if(on_event::<GamepadEvent>), gamepad_connections.run_if(on_event::<GamepadEvent>),
combine_controls,
) )
.chain()
.in_set(ControllerSet::CollectInputs) .in_set(ControllerSet::CollectInputs)
.run_if(in_state(GameState::Playing)), .run_if(in_state(GameState::Playing)),
); );
} }
fn combine_controls(controls: Res<Controls>, mut combined_controls: ResMut<ControlState>) {
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 /// Applies a square deadzone to a Vec2
fn deadzone_square(v: Vec2, min: f32) -> Vec2 { fn deadzone_square(v: Vec2, min: f32) -> Vec2 {
Vec2::new( Vec2::new(
@@ -125,6 +143,8 @@ fn gamepad_controls(
} }
fn mouse_rotate(mut mouse: EventReader<MouseMotion>, mut controls: ResMut<Controls>) { fn mouse_rotate(mut mouse: EventReader<MouseMotion>, mut controls: ResMut<Controls>) {
controls.keyboard_state.look_dir = Vec2::ZERO;
for ev in mouse.read() { for ev in mouse.read() {
controls.keyboard_state.look_dir += ev.delta; controls.keyboard_state.look_dir += ev.delta;
} }

View File

@@ -31,9 +31,9 @@ pub struct ControlState {
} }
#[derive(Resource, Debug, Default)] #[derive(Resource, Debug, Default)]
pub struct Controls { struct Controls {
pub keyboard_state: ControlState, keyboard_state: ControlState,
pub gamepad_state: Option<ControlState>, gamepad_state: Option<ControlState>,
} }
#[derive(Event)] #[derive(Event)]
@@ -44,6 +44,7 @@ pub struct SelectedController(ControllerSet);
pub fn plugin(app: &mut App) { pub fn plugin(app: &mut App) {
app.init_resource::<SelectedController>(); app.init_resource::<SelectedController>();
app.init_resource::<ControlState>();
app.add_plugins(controls::plugin); app.add_plugins(controls::plugin);
app.add_plugins(controller_common::plugin); app.add_plugins(controller_common::plugin);