Split crate into shared logic library and binary crate (#52) (#53)

This commit is contained in:
extrawurst
2025-06-29 12:45:25 +02:00
committed by GitHub
parent 5d4c7630ef
commit 7996d632f7
65 changed files with 497 additions and 82 deletions

View File

@@ -0,0 +1,116 @@
use super::{ControlState, ControllerSet, Controls};
use crate::{
GameState,
abilities::TriggerStateRes,
animation::AnimationFlags,
character::HasCharacterAnimations,
control::{controller_common::MovementSpeedFactor, controls::ControllerSettings},
player::{Player, PlayerBodyMesh},
};
use bevy::prelude::*;
use happy_feet::prelude::{Grounding, KinematicVelocity, MoveInput};
pub struct CharacterControllerPlugin;
impl Plugin for CharacterControllerPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
(set_animation_flags, rotate_view, apply_controls)
.chain()
.in_set(ControllerSet::ApplyControlsRun)
.run_if(in_state(GameState::Playing)),
);
}
}
/// Sets the movement flag, which is an indicator for the rig animation and the braking system.
fn set_animation_flags(
mut flags: Query<&mut AnimationFlags>,
controls: Res<Controls>,
trigger: Res<TriggerStateRes>,
player: Single<(&Grounding, &HasCharacterAnimations), With<Player>>,
) {
let mut direction = controls.keyboard_state.move_dir;
let deadzone = 0.2;
let (grounding, has_anims) = *player;
let mut flags = flags.get_mut(*has_anims.collection()).unwrap();
if let Some(gamepad) = controls.gamepad_state {
direction += gamepad.move_dir;
}
if flags.any_direction {
if direction.length_squared() < deadzone {
flags.any_direction = false;
}
} else if direction.length_squared() > deadzone {
flags.any_direction = true;
}
if flags.shooting != trigger.is_active() {
flags.shooting = trigger.is_active();
}
// `apply_controls` sets the jump flag when the player actually jumps.
// Unset the flag on hitting the ground
if grounding.is_grounded() {
flags.jumping = false;
}
}
fn rotate_view(
controls: Res<ControlState>,
mut player: Query<&mut Transform, With<PlayerBodyMesh>>,
) {
if controls.view_mode {
return;
}
for mut tr in player.iter_mut() {
tr.rotate_y(controls.look_dir.x * -0.001);
}
}
fn apply_controls(
controls: Res<ControlState>,
mut character: Query<(
&mut MoveInput,
&mut Grounding,
&mut KinematicVelocity,
&ControllerSettings,
&MovementSpeedFactor,
&HasCharacterAnimations,
)>,
rig_transform_q: Option<Single<&GlobalTransform, With<PlayerBodyMesh>>>,
mut anim_flags: Query<&mut AnimationFlags>,
) {
let Ok((mut move_input, mut grounding, mut velocity, settings, move_factor, has_anims)) =
character.single_mut()
else {
return;
};
let mut flags = anim_flags.get_mut(*has_anims.collection()).unwrap();
let mut direction = -controls.move_dir.extend(0.0).xzy();
if let Some(ref rig_transform) = rig_transform_q {
direction = (rig_transform.forward() * direction.z) + (rig_transform.right() * direction.x);
}
let ground_normal = *grounding.normal().unwrap_or(Dir3::Y);
let y_projection = direction.project_onto(ground_normal);
direction -= y_projection;
direction = direction.normalize_or_zero();
move_input.set(direction * move_factor.0);
if controls.jump && grounding.is_grounded() {
flags.jumping = true;
flags.just_jumped = true;
happy_feet::movement::jump(settings.jump_force, &mut velocity, &mut grounding, Dir3::Y)
}
}