Skip to content

Commit

Permalink
Merge pull request #24 from Waridley/char_ctrl
Browse files Browse the repository at this point in the history
Character controller improvements
  • Loading branch information
Waridley authored Feb 8, 2024
2 parents bc54c34 + 72b1a7e commit 30f42c8
Show file tree
Hide file tree
Showing 9 changed files with 534 additions and 242 deletions.
4 changes: 3 additions & 1 deletion .idea/runConfigurations/Run__debug_.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rs/assets/pickups/pickup_material.mat.ron
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ExtendedMaterial(
extension: BubbleMaterial(
glow_color: Rgba ( red: 4.0, green: 1.0, blue: 0.0, alpha: 0.15 ),
glow_color: Rgba ( red: 4.0, green: 1.0, blue: 0.0, alpha: 0.12 ),
),
base: StandardMaterial(
specular_transmission: 1.0,
Expand Down
43 changes: 31 additions & 12 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]

use crate::mats::BubbleMaterial;
use bevy::{
diagnostic::FrameTimeDiagnosticsPlugin, pbr::ExtendedMaterial, prelude::*,
render::RenderPlugin, window::PrimaryWindow,
};
use bevy_common_assets::ron::RonAssetPlugin;
use bevy_kira_audio::AudioPlugin;
use bevy_pkv::PkvStore;
use bevy_rapier3d::prelude::*;
use particles::ParticlesPlugin;
use player::ctrl::CtrlVel;
use std::{f32::consts::*, fmt::Debug, time::Duration};
use util::IntoFnPlugin;
use util::RonReflectAssetLoader;
use util::{IntoFnPlugin, RonReflectAssetLoader};

#[allow(unused_imports, clippy::single_component_path_imports)]
#[cfg(all(debug_assertions, not(target_arch = "wasm32")))]
use bevy_dylib;
use bevy_rapier3d::plugin::PhysicsSet::StepSimulation;

pub mod enemies;
pub mod mats;
Expand All @@ -33,9 +37,9 @@ pub mod util;
/// Epsilon
pub const EPS: f32 = 1.0e-5;
/// Rotational epsilon in radians
pub const R_EPS: f32 = TAU / (360.0 * 4.0);
pub const R_EPS: f32 = TAU / 360.0; // 1 degree
/// Fixed delta time
pub const DT: f32 = 1.0 / 128.0;
pub const DT: f32 = 1.0 / 30.0;
/// Up vector
pub const UP: Vect = Vect::Z;

Expand Down Expand Up @@ -115,7 +119,10 @@ pub fn game_plugin(app: &mut App) -> &mut App {
MaterialPlugin::<ExtendedMaterial<StandardMaterial, BubbleMaterial>>::default(),
))
.add_systems(Startup, startup)
.add_systems(Update, (terminal_velocity, fullscreen))
.add_systems(
Update,
(terminal_velocity.before(StepSimulation), fullscreen),
)
.add_systems(PostUpdate, (despawn_oob,));
type BubbleMatExt = ExtendedMaterial<StandardMaterial, BubbleMaterial>;
let registry = app.world.get_resource::<AppTypeRegistry>().unwrap().clone();
Expand All @@ -124,7 +131,10 @@ pub fn game_plugin(app: &mut App) -> &mut App {
reg.register::<BubbleMaterial>();
reg.register::<BubbleMatExt>();
}
app.register_asset_loader(RonReflectAssetLoader::<BubbleMatExt>::new(registry, vec!["mat.ron"]));
app.register_asset_loader(RonReflectAssetLoader::<BubbleMatExt>::new(
registry,
vec!["mat.ron"],
));
app
}

Expand All @@ -146,11 +156,20 @@ impl AbsoluteBounds {

pub type InBounds = bool;

fn despawn_oob(mut cmds: Commands, bounds: Res<AbsoluteBounds>, q: Query<(Entity, &Transform)>) {
for (id, xform) in &q {
if !bounds.test(xform.translation) {
bevy::log::warn!("Entity {id:?} is way out of bounds. Despawning.");
cmds.entity(id).despawn()
#[derive(Component, Debug)]
pub struct NeverDespawn;

fn despawn_oob(mut cmds: Commands, bounds: Res<AbsoluteBounds>, mut q: Query<(Entity, &mut GlobalTransform, Has<NeverDespawn>)>) {
for (id, mut xform, never_despawn) in &mut q {
if !bounds.test(xform.translation()) {
let plan = if never_despawn {
*xform = GlobalTransform::default();
"Resetting transform to zero"
} else {
cmds.entity(id).despawn();
"Despawning"
};
bevy::log::warn!("Entity {id:?} is way out of bounds. {plan}...");
}
}
}
Expand Down
7 changes: 1 addition & 6 deletions rs/src/pickups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ pub fn plugin(app: &mut App) -> &mut App {
#[derive(Resource, Default, Debug, Clone, Deref, DerefMut)]
pub struct PopSfx(pub Handle<AudioSource>);

pub fn setup(
mut cmds: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut mats: ResMut<Assets<ExtendedMaterial<StandardMaterial, BubbleMaterial>>>,
asset_server: Res<AssetServer>,
) {
pub fn setup(mut cmds: Commands, mut meshes: ResMut<Assets<Mesh>>, asset_server: Res<AssetServer>) {
cmds.insert_resource(SpawnTimer(Timer::new(
Duration::from_secs(2),
TimerMode::Repeating,
Expand Down
136 changes: 79 additions & 57 deletions rs/src/player.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{terminal_velocity, TerminalVelocity, R_EPS};

use crate::{pickups::MissSfx, settings::Settings, util::IntoFnPlugin};
use bevy::{
ecs::system::EntityCommands,
prelude::{
Expand All @@ -11,24 +12,30 @@ use bevy::{
};
use bevy_kira_audio::{Audio, AudioControl};
use bevy_rapier3d::{
control::KinematicCharacterController,
dynamics::{CoefficientCombineRule::Min, Velocity},
geometry::{Collider, Friction},
math::Vect,
plugin::{systems::update_character_controls, PhysicsSet::Writeback},
na::Vector3,
parry::math::Isometry,
plugin::PhysicsSet::StepSimulation,
prelude::{RigidBody::KinematicPositionBased, *},
};
use camera::spawn_camera;
use ctrl::CtrlVel;
use ctrl::{CtrlState, CtrlVel};
use enum_components::{ERef, EntityEnumCommands, EnumComponent};
use input::{AoESound, PlayerAction};
use leafwing_input_manager::prelude::*;
use nanorand::Rng;
use particles::{
update::{Linear, TargetScale},
InitialGlobalTransform, InitialTransform, Lifetime, ParticleBundle, PreviousGlobalTransform,
PreviousTransform, Spewer, SpewerBundle,
};
use rapier3d::{math::Point, prelude::Aabb};
use prefs::PlayerPrefs;
use rapier3d::{
math::Point,
prelude::{Aabb, Ball, SharedShape},
};
use std::{
f32::consts::*,
num::NonZeroU8,
Expand All @@ -51,29 +58,40 @@ pub const SLIDE_ANGLE: f32 = FRAC_PI_3 - R_EPS;
pub const HOVER_HEIGHT: f32 = 2.0;
const G1: Group = Group::GROUP_1;

pub const CHAR_COLLIDER: Ball = Ball { radius: 1.2 };

#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum InterpolatedXforms {
Propagate,
Sync,
}

pub fn plugin(app: &mut App) -> &mut App {
app.add_plugins(input::plugin.plugfn())
.add_systems(Startup, setup)
.add_systems(
Update,
(
ctrl::gravity,
ctrl::repel_ground.after(ctrl::gravity),
ctrl::reset_jump_on_ground.after(ctrl::repel_ground),
ctrl::gravity.before(terminal_velocity),
// ctrl::repel_ground.after(ctrl::gravity),
input::movement_input.before(terminal_velocity),
camera::position_target.after(terminal_velocity),
camera::follow_target.after(camera::position_target),
ctrl::move_player
.after(terminal_velocity)
.before(update_character_controls),
save_tmp_transform
.after(update_character_controls)
.before(Writeback),
load_tmp_transform.after(Writeback),
.before(StepSimulation)
.after(terminal_velocity),
ctrl::reset_jump_on_ground.after(ctrl::move_player),
// propagate_transforms.in_set(InterpolatedXforms::Propagate),
// sync_simple_transforms.in_set(InterpolatedXforms::Sync),
// ctrl::save_tmp_transform
// .after(ctrl::move_player)
// .before(Writeback),
// ctrl::load_tmp_transform.after(Writeback),
idle,
play_death_sound,
),
)
// .configure_sets(Update, (InterpolatedXforms::Propagate, InterpolatedXforms::Sync).chain().after(ctrl::move_player))
.add_systems(
Last,
(reset_oob, countdown_respawn, spawn_players, kill_on_key),
Expand Down Expand Up @@ -193,16 +211,6 @@ pub enum PlayerEntity {
Arms,
Arm(PlayerArm),
}
use crate::{
pickups::MissSfx,
player::{
ctrl::{load_tmp_transform, save_tmp_transform, CtrlState},
input::{AoESound, PlayerAction},
prefs::PlayerPrefs,
},
settings::Settings,
util::IntoFnPlugin,
};
use player_entity::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -282,14 +290,14 @@ pub fn spawn_players(

let id = event.id;
let owner = BelongsToPlayer::with_id(id);
let char_collider = Collider::ball(1.2);
let char_collider = Collider::from(SharedShape::new(CHAR_COLLIDER));
let mut root = cmds
.spawn((
Name::new(format!("Player{}", owner.0.get())),
owner,
TerminalVelocity(Velocity {
linvel: Vect::splat(128.0),
angvel: Vect::new(0.0, 0.0, TAU * 60.0), // one rotation per frame at 60 fps
linvel: Vect::splat(96.0),
angvel: Vect::new(0.0, 0.0, PI / crate::DT), // Half a rotation per physics tick
}),
KinematicPositionBased,
TransformBundle::default(),
Expand Down Expand Up @@ -328,19 +336,14 @@ fn build_player_scene(
arm_particle_mesh: Handle<Mesh>,
) {
player_controller(root, owner, char_collider);
player_vis(root, owner, vis, particle_mesh);

root.with_children(|builder| {
let mut arms = builder
.spawn((
Name::new(format!("Player{}.Arms", owner.0.get())),
TransformBundle::default(),
VisibilityBundle::default(),
RotVel::new(8.0),
))
.with_enum(Arms);
player_arms(&mut arms, owner, arm_meshes, arm_particle_mesh);
});
player_vis(
root,
owner,
vis,
particle_mesh,
arm_meshes,
arm_particle_mesh,
);
}

fn player_controller(root: &mut EntityCommands, owner: BelongsToPlayer, char_collider: Collider) {
Expand All @@ -356,19 +359,21 @@ fn player_controller(root: &mut EntityCommands, owner: BelongsToPlayer, char_col
Name::new(format!("Player{}.Controller", owner.0.get())),
owner,
char_collider,
Restitution::new(0.5),
Ccd::enabled(),
TransformBundle::default(),
CtrlVel::default(),
CollisionGroups::new(Group::GROUP_1, !Group::GROUP_1),
KinematicCharacterController {
up: Vect::Z,
snap_to_ground: None,
autostep: None,
max_slope_climb_angle: CLIMB_ANGLE,
min_slope_slide_angle: SLIDE_ANGLE,
filter_flags: QueryFilterFlags::EXCLUDE_SENSORS,
filter_groups: Some(CollisionGroups::new(G1, !G1)),
..default()
},
// KinematicCharacterController {
// up: Vect::Z,
// snap_to_ground: None,
// autostep: None,
// max_slope_climb_angle: CLIMB_ANGLE,
// min_slope_slide_angle: SLIDE_ANGLE,
// filter_flags: QueryFilterFlags::EXCLUDE_SENSORS,
// filter_groups: Some(CollisionGroups::new(G1, !G1)),
// ..default()
// },
InputManagerBundle::<PlayerAction> {
input_map,
..default()
Expand All @@ -386,19 +391,23 @@ fn player_vis(
owner: BelongsToPlayer,
vis: SceneBundle,
particle_mesh: MaterialMeshBundle<StandardMaterial>,
arm_meshes: [(MaterialMeshBundle<StandardMaterial>, PlayerArm); 3],
arm_particle_mesh: Handle<Mesh>,
) {
let camera_pivot = camera::spawn_pivot(root.commands(), owner).id();
let ship_center = root
.commands()
.spawn((
Name::new(format!("Player{}.ShipCenter", owner.0.get())),
owner,
TransformBundle::from_transform(Transform {
translation: Vec3::NEG_Z * 0.64,
rotation: Quat::from_rotation_x(FRAC_PI_2),
..default()
}),
// TransformBundle::default(),
TransformBundle::from_transform(Transform::from_translation(Vec3::NEG_Z * 0.64)),
TransformInterpolation {
start: None,
end: Some(Isometry::new(
Vector3::new(0.0, 0.0, -0.64),
Vector3::default(),
)),
},
VisibilityBundle::default(), // for children ComputedVisibility
))
.set_enum(ShipCenter)
Expand All @@ -408,7 +417,9 @@ fn player_vis(
.spawn((
Name::new(format!("Player{}.ShipCenter.Ship", owner.0.get())),
owner,
TransformBundle::default(),
TransformBundle::from_transform(Transform::from_rotation(
Quat::from_rotation_x(FRAC_PI_2),
)),
VisibilityBundle::default(),
))
.set_enum(Ship)
Expand Down Expand Up @@ -493,6 +504,17 @@ fn player_vis(
));
});
})
.with_children(|builder| {
let mut arms = builder
.spawn((
Name::new(format!("Player{}.ShipCenter.Arms", owner.0.get())),
TransformBundle::from_transform(Transform::from_translation(Vec3::Z * 0.64)),
VisibilityBundle::default(),
RotVel::new(8.0),
))
.with_enum(Arms);
player_arms(&mut arms, owner, arm_meshes, arm_particle_mesh);
})
.add_child(camera_pivot)
.id();
root.add_child(ship_center);
Expand Down Expand Up @@ -582,7 +604,7 @@ fn player_arms(
};
builder
.spawn((
Name::new(format!("Player{}.Arms.{which:?}", owner.0.get())),
Name::new(format!("Player{}.ShipCenter.Arms.{which:?}", owner.0.get())),
owner,
arm,
spewer,
Expand Down
Loading

0 comments on commit 30f42c8

Please sign in to comment.