Simplify working with controls (#27)
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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>,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user