Compare commits

..

2 commits

Author SHA1 Message Date
Joe Ardent
3d0d86f24c compiles and runs, but crashes 2024-07-15 17:30:26 -07:00
Joe Ardent
4d94f2bfa4 update deps for switching to Avian3d 2024-07-15 17:30:26 -07:00
11 changed files with 172 additions and 121 deletions

23
Cargo.lock generated
View file

@ -284,9 +284,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "avian3d" name = "avian3d"
version = "0.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8da53296a1bc166b84f99aa7c6b9d8c10c71f0c022bc4fc72dd1fc49323b29" checksum = "54325576b6efa46576db611624db749b553d0c66e439862bdc60c43e01f012f9"
dependencies = [ dependencies = [
"avian_derive", "avian_derive",
"bevy", "bevy",
@ -1223,9 +1223,9 @@ dependencies = [
[[package]] [[package]]
name = "blake3" name = "blake3"
version = "1.5.2" version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92" checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"arrayvec", "arrayvec",
@ -1296,9 +1296,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.6.0" version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
[[package]] [[package]]
name = "calloop" name = "calloop"
@ -1316,13 +1316,12 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.1.2" version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47de7e88bbbd467951ae7f5a6f34f70d1b4d9cfce53d5fd70f74ebe118b3db56" checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
"once_cell",
] ]
[[package]] [[package]]
@ -3067,7 +3066,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall 0.5.2", "redox_syscall 0.5.3",
"smallvec", "smallvec",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
@ -3367,9 +3366,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.2" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
] ]

View file

@ -1,7 +1,7 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use bevy::{ use bevy::{
prelude::{Component, ReflectResource, Resource, Vec3}, prelude::{Component, ReflectResource, Resource},
reflect::Reflect, reflect::Reflect,
}; };
@ -26,21 +26,6 @@ impl ActionDebugInstant {
} }
} }
#[derive(Debug, Component)]
pub(super) struct Tunneling {
pub frames: usize,
pub dir: Vec3,
}
impl Default for Tunneling {
fn default() -> Self {
Tunneling {
frames: 15,
dir: Vec3::ZERO,
}
}
}
#[derive(Debug, Resource, Reflect)] #[derive(Debug, Resource, Reflect)]
#[reflect(Resource)] #[reflect(Resource)]
pub struct MovementSettings { pub struct MovementSettings {

View file

@ -1,6 +1,6 @@
use avian3d::prelude::*; use avian3d::prelude::{PhysicsPlugins, SubstepCount};
use bevy::{ use bevy::{
app::{Startup, Update}, app::Update,
diagnostic::FrameTimeDiagnosticsPlugin, diagnostic::FrameTimeDiagnosticsPlugin,
ecs::reflect::ReflectResource, ecs::reflect::ReflectResource,
prelude::{App, IntoSystemConfigs, Plugin, Resource}, prelude::{App, IntoSystemConfigs, Plugin, Resource},
@ -29,14 +29,14 @@ impl Plugin for CyberActionPlugin {
.init_resource::<CyberLean>() .init_resource::<CyberLean>()
.register_type::<CyberLean>() .register_type::<CyberLean>()
.register_type::<CatControllerSettings>() .register_type::<CatControllerSettings>()
.add_plugins(( .add_plugins((PhysicsPlugins::default(), FrameTimeDiagnosticsPlugin))
PhysicsPlugins::default(),
FrameTimeDiagnosticsPlugin::default(),
))
.insert_resource(SubstepCount(12)) .insert_resource(SubstepCount(12))
.add_systems( .add_systems(
Update, Update,
(gravity, cyber_lean, falling_cat, input_forces).chain(), (
gravity,
(cyber_lean, suspension, falling_cat, input_forces).after(clear_forces),
),
); );
} }
} }

View file

@ -1,17 +1,17 @@
use std::f32::consts::{FRAC_PI_3, FRAC_PI_4}; use std::f32::consts::{FRAC_PI_3, FRAC_PI_4};
use avian3d::{ use avian3d::{
dynamics::solver::xpbd::AngularConstraint, parry::mass_properties::MassProperties, prelude::*, dynamics::solver::xpbd::AngularConstraint,
}; prelude::{
use bevy::prelude::{ ColliderMassProperties, ExternalForce, ExternalTorque, Gravity, LinearVelocity,
Commands, Entity, Quat, Query, Res, ResMut, Time, Transform, Vec3, With, Without, PrismaticJoint, RigidBodyQuery,
},
}; };
use bevy::prelude::{Quat, Query, Res, ResMut, Time, Transform, Vec3, With, Without};
//#[cfg(feature = "inspector")] use super::{CatControllerSettings, CatControllerState, CyberLean, MovementSettings};
//use super::ActionDebugInstant;
use super::{CatControllerSettings, CatControllerState, CyberLean, MovementSettings, Tunneling};
use crate::{ use crate::{
bike::{CyberBikeBody, CyberSteering, CyberWheel, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}, bike::{CyberBikeBody, CyberFork, CyberSpring, CyberSteering, CyberWheel, WheelConfig},
input::InputState, input::InputState,
}; };
@ -37,14 +37,42 @@ fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
/// The gravity vector points from the cyberbike to the center of the planet. /// The gravity vector points from the cyberbike to the center of the planet.
pub(super) fn gravity( pub(super) fn gravity(
mut query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>, xform: Query<&Transform, With<CyberBikeBody>>,
settings: Res<MovementSettings>, settings: Res<MovementSettings>,
mut gravity: ResMut<Gravity>, mut gravity: ResMut<Gravity>,
#[cfg(feature = "inspector")] mut debug_instant: ResMut<ActionDebugInstant>,
) { ) {
let (xform, mut forces) = query.single_mut(); let xform = xform.single();
*gravity = Gravity(xform.translation.normalize() * -settings.gravity); *gravity = Gravity(xform.translation.normalize() * -settings.gravity);
forces.clear();
// clear all external forces
}
pub(super) fn clear_forces(mut forces: Query<(&mut ExternalForce, &mut ExternalTorque)>) {
for (mut force, mut torque) in forces.iter_mut() {
force.clear();
torque.clear();
}
}
pub(super) fn suspension(
movment_settings: Res<MovementSettings>,
wheel_config: Res<WheelConfig>,
mass: Query<&ColliderMassProperties, With<CyberBikeBody>>,
mut axels: Query<(&mut ExternalForce, &CyberSpring, &Transform)>,
) {
let mass = if let Ok(mass) = mass.get_single() {
mass.mass.0
} else {
1.0
};
let gravity = movment_settings.gravity;
let mag = -wheel_config.stiffness * mass * gravity;
for (mut force, spring, xform) in axels.iter_mut() {
let spring = mag * spring.0;
let spring = xform.translation + spring;
let _ = force.apply_force(spring);
}
} }
/// The desired lean angle, given steering input and speed. /// The desired lean angle, given steering input and speed.
@ -106,26 +134,30 @@ pub(super) fn input_forces(
settings: Res<MovementSettings>, settings: Res<MovementSettings>,
input: Res<InputState>, input: Res<InputState>,
time: Res<Time>, time: Res<Time>,
axle: Query<Entity, With<CyberSteering>>, fork: Query<&PrismaticJoint, With<CyberFork>>,
mut axle: Query<(RigidBodyQuery, &Transform), With<CyberSteering>>,
mut braking_query: Query<&mut ExternalTorque, With<CyberWheel>>, mut braking_query: Query<&mut ExternalTorque, With<CyberWheel>>,
mut body_query: Query< mut body_query: Query<
( (
Entity, RigidBodyQuery,
&Transform, &Transform,
&ColliderMassProperties, &ColliderMassProperties,
&mut ExternalForce, &mut ExternalForce,
), ),
With<CyberBikeBody>, (With<CyberBikeBody>, Without<CyberSteering>),
>, >,
) { ) {
let (bike, xform, mass, mut forces) = body_query.single_mut(); let Ok((mut bike, xform, mass, mut forces)) = body_query.get_single_mut() else {
bevy::log::warn!("no bike body found");
return;
};
let dt = time.delta_seconds(); let dt = time.delta_seconds();
// thrust // thrust
let thrust = xform.forward() * input.throttle * settings.accel; let thrust = xform.forward() * input.throttle * settings.accel;
let point = xform.translation + *xform.back(); let point = xform.translation + *xform.back();
*forces.apply_force_at_point(dt * thrust, point, mass.center_of_mass.0); let _ = *forces.apply_force_at_point(dt * thrust, point, mass.center_of_mass.0);
// brake + thrust // brake + thrust
for mut motor in braking_query.iter_mut() { for mut motor in braking_query.iter_mut() {
@ -142,7 +174,14 @@ pub(super) fn input_forces(
// steering // steering
let _angle = yaw_to_angle(input.yaw); let _angle = yaw_to_angle(input.yaw);
let _axle = axle.single(); let (mut axle, xform) = axle.single_mut();
//steering.align_orientation(bike, steering, rotation_difference, lagrange,
// compliance, dt) let cur_rot = xform.rotation;
let fork = fork.single();
let axis = fork.free_axis.normalize();
let new = Quat::from_axis_angle(axis, _angle);
let diff = (new - cur_rot).to_scaled_axis();
let mut compliance = 1.0;
fork.align_orientation(&mut axle, &mut bike, diff, &mut compliance, 1.0, dt);
} }

View file

@ -37,24 +37,20 @@ pub(super) fn spawn_cyberbike(
let scene = asset_server.load("cb-no-y_up.glb#Scene0"); let scene = asset_server.load("cb-no-y_up.glb#Scene0");
let spatialbundle = SpatialBundle { let body_collider =
transform: xform,
..Default::default()
};
let body =
Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8)); Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8));
let mass_props = MassPropertiesBundle::new_computed(&body, 0.6);
let bike = commands let bike = commands
.spawn(RigidBody::Dynamic) .spawn(SpatialBundle::from_transform(xform))
.insert(spatialbundle)
.insert(( .insert((
body, RigidBody::Dynamic,
mass_props.clone(), body_collider,
bike_collision_group, bike_collision_group,
restitution, restitution,
friction, friction,
SleepingDisabled, SleepingDisabled,
CyberBikeBody,
CatControllerState::default(),
ColliderDensity(0.6),
LinearDamping(0.1), LinearDamping(0.1),
AngularDamping(2.0), AngularDamping(2.0),
LinearVelocity::ZERO, LinearVelocity::ZERO,
@ -68,8 +64,6 @@ pub(super) fn spawn_cyberbike(
..Default::default() ..Default::default()
}); });
}) })
.insert(CyberBikeBody)
.insert(CatControllerState::default())
.id(); .id();
spawn_wheels(&mut commands, bike, &wheel_conf, &mut meshterials); spawn_wheels(&mut commands, bike, &wheel_conf, &mut meshterials);

View file

@ -1,4 +1,5 @@
use bevy::{ use bevy::{
math::Vec3,
prelude::{Component, ReflectResource, Resource}, prelude::{Component, ReflectResource, Resource},
reflect::Reflect, reflect::Reflect,
}; };
@ -6,12 +7,18 @@ use bevy::{
#[derive(Component)] #[derive(Component)]
pub struct CyberBikeBody; pub struct CyberBikeBody;
#[derive(Clone, Component)] #[derive(Clone, Copy, Component)]
pub struct CyberSteering; pub struct CyberSteering;
#[derive(Clone, Debug, Component)] #[derive(Clone, Copy, Debug, Component)]
pub struct CyberWheel; pub struct CyberWheel;
#[derive(Clone, Debug, Component)]
pub struct CyberSpring(pub Vec3);
#[derive(Clone, Debug, Component)]
pub struct CyberFork;
#[derive(Resource, Reflect)] #[derive(Resource, Reflect)]
#[reflect(Resource)] #[reflect(Resource)]
pub struct WheelConfig { pub struct WheelConfig {
@ -35,7 +42,7 @@ impl Default for WheelConfig {
rear_back: 1.0, rear_back: 1.0,
y: -0.1, y: -0.1,
limits: [-0.5, 0.1], limits: [-0.5, 0.1],
stiffness: 190.0, stiffness: 3.0,
damping: 8.0, damping: 8.0,
radius: 0.25, radius: 0.25,
thickness: 0.11, thickness: 0.11,

View file

@ -3,7 +3,7 @@ mod components;
mod wheels; mod wheels;
use bevy::{ use bevy::{
app::PostStartup, app::{PostStartup, Startup},
prelude::{App, Assets, Mesh, Plugin, ResMut, StandardMaterial}, prelude::{App, Assets, Mesh, Plugin, ResMut, StandardMaterial},
}; };
@ -23,6 +23,6 @@ impl Plugin for CyberBikePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.insert_resource(WheelConfig::default()) app.insert_resource(WheelConfig::default())
.register_type::<WheelConfig>() .register_type::<WheelConfig>()
.add_systems(PostStartup, spawn_cyberbike); .add_systems(Startup, spawn_cyberbike);
} }
} }

View file

@ -1,7 +1,10 @@
use avian3d::prelude::*; use avian3d::prelude::*;
use bevy::prelude::{Torus as Tire, *}; use bevy::prelude::{Torus as Tire, *};
use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}; use super::{
CyberFork, CyberSpring, CyberSteering, CyberWheel, Meshterial, WheelConfig,
BIKE_WHEEL_COLLISION_GROUP,
};
pub fn spawn_wheels( pub fn spawn_wheels(
commands: &mut Commands, commands: &mut Commands,
@ -12,7 +15,6 @@ pub fn spawn_wheels(
let (membership, filter) = BIKE_WHEEL_COLLISION_GROUP; let (membership, filter) = BIKE_WHEEL_COLLISION_GROUP;
let wheels_collision_group = CollisionLayers::new(membership, filter); let wheels_collision_group = CollisionLayers::new(membership, filter);
let wheel_y = conf.y; let wheel_y = conf.y;
let stiffness = conf.stiffness;
let not_sleeping = SleepingDisabled; let not_sleeping = SleepingDisabled;
let ccd = SweptCcd::NON_LINEAR.include_dynamic(false); let ccd = SweptCcd::NON_LINEAR.include_dynamic(false);
let limits = conf.limits; let limits = conf.limits;
@ -84,11 +86,26 @@ pub fn spawn_wheels(
)) ))
.id(); .id();
let axel = if let Some(ref steering) = steering { let spring = CyberSpring(suspension_axis);
commands.spawn((RigidBody::Dynamic, ExternalForce::ZERO, steering.clone())) let axel = if let Some(steering) = steering {
commands.spawn((
RigidBody::Dynamic,
ExternalForce::ZERO,
steering,
spring,
Collider::sphere(0.1),
ColliderDensity(0.1),
))
} else { } else {
commands.spawn((RigidBody::Dynamic, ExternalForce::ZERO)) commands.spawn((
RigidBody::Dynamic,
ExternalForce::ZERO,
spring,
Collider::sphere(0.1),
ColliderDensity(0.1),
))
} }
.insert(SpatialBundle::default())
.id(); .id();
let axel_joint = RevoluteJoint::new(axel, wheel).with_aligned_axis(Vec3::NEG_X); let axel_joint = RevoluteJoint::new(axel, wheel).with_aligned_axis(Vec3::NEG_X);
commands.spawn(axel_joint); commands.spawn(axel_joint);
@ -100,7 +117,7 @@ pub fn spawn_wheels(
.with_local_anchor_1(Vec3::new(0.0, 0.0, 0.1)) .with_local_anchor_1(Vec3::new(0.0, 0.0, 0.1))
.with_local_anchor_2(offset) .with_local_anchor_2(offset)
.with_limits(limits[0], limits[1]); .with_limits(limits[0], limits[1]);
commands.spawn(joint); commands.spawn((joint, CyberFork));
} else { } else {
let joint = PrismaticJoint::new(axel, bike) let joint = PrismaticJoint::new(axel, bike)
.with_free_axis(suspension_axis) .with_free_axis(suspension_axis)

View file

@ -81,7 +81,7 @@ fn follow_cyberbike(
// handle input pitch // handle input pitch
let angle = input.pitch.powi(3) * MAX_PITCH; let angle = input.pitch.powi(3) * MAX_PITCH;
let axis = cam_xform.right(); let axis = cam_xform.right();
cam_xform.rotate(Quat::from_axis_angle(axis, angle)); cam_xform.rotate(Quat::from_axis_angle(*axis, angle));
} }
CyberCameras::Debug => { CyberCameras::Debug => {
let mut ncx = bike_xform.to_owned(); let mut ncx = bike_xform.to_owned();
@ -101,7 +101,7 @@ fn update_active_camera(
) { ) {
// find the camera with the current state, set it as the ActiveCamera // find the camera with the current state, set it as the ActiveCamera
query.iter_mut().for_each(|(mut cam, cyber)| { query.iter_mut().for_each(|(mut cam, cyber)| {
if cyber.eq(&state.0) { if cyber.eq(&state.get()) {
cam.is_active = true; cam.is_active = true;
} else { } else {
cam.is_active = false; cam.is_active = false;
@ -112,13 +112,13 @@ fn update_active_camera(
fn cycle_cam_state( fn cycle_cam_state(
state: Res<State<CyberCameras>>, state: Res<State<CyberCameras>>,
mut next: ResMut<NextState<CyberCameras>>, mut next: ResMut<NextState<CyberCameras>>,
mut keys: ResMut<Input<KeyCode>>, mut keys: ResMut<ButtonInput<KeyCode>>,
) { ) {
if keys.just_pressed(KeyCode::D) { if keys.just_pressed(KeyCode::KeyD) {
let new_state = state.0.next(); let new_state = state.get().next();
info!("{:?}", new_state); info!("{:?}", new_state);
next.set(new_state); next.set(new_state);
keys.reset(KeyCode::D); keys.reset(KeyCode::KeyD);
} }
} }
@ -132,9 +132,10 @@ impl Plugin for CyberCamPlugin {
fn common(app: &mut bevy::prelude::App) { fn common(app: &mut bevy::prelude::App) {
app.insert_resource(DebugCamOffset::default()) app.insert_resource(DebugCamOffset::default())
.add_startup_system(setup_cybercams) .add_systems(Startup, setup_cybercams)
.add_state::<CyberCameras>() .init_state::<CyberCameras>()
.add_system(cycle_cam_state) .add_systems(
.add_system(update_active_camera) Update,
.add_system(follow_cyberbike); (cycle_cam_state, update_active_camera, follow_cyberbike),
);
} }

View file

@ -4,6 +4,9 @@ use crate::planet::PLANET_RADIUS;
pub const LIGHT_RANGE: f32 = 90.0; pub const LIGHT_RANGE: f32 = 90.0;
static BLUE: Color = Color::linear_rgb(0.0, 0.0, 1.0);
static PINK: Color = Color::linear_rgb(199.0 / 255.0, 21.0 / 255.0, 113.0 / 255.0);
fn spawn_static_lights( fn spawn_static_lights(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
@ -12,7 +15,7 @@ fn spawn_static_lights(
let pink_light = PointLight { let pink_light = PointLight {
intensity: 1_00.0, intensity: 1_00.0,
range: LIGHT_RANGE, range: LIGHT_RANGE,
color: Color::PINK, color: PINK,
radius: 1.0, radius: 1.0,
shadows_enabled: true, shadows_enabled: true,
..Default::default() ..Default::default()
@ -21,7 +24,7 @@ fn spawn_static_lights(
let blue_light = PointLight { let blue_light = PointLight {
intensity: 1_000.0, intensity: 1_000.0,
range: LIGHT_RANGE, range: LIGHT_RANGE,
color: Color::BLUE, color: BLUE,
radius: 1.0, radius: 1.0,
shadows_enabled: true, shadows_enabled: true,
..Default::default() ..Default::default()
@ -48,16 +51,10 @@ fn spawn_static_lights(
}) })
.with_children(|builder| { .with_children(|builder| {
builder.spawn(PbrBundle { builder.spawn(PbrBundle {
mesh: meshes.add( mesh: meshes.add(Mesh::from(Sphere::new(10.0))),
Mesh::try_from(shape::Icosphere {
radius: 10.0,
subdivisions: 2,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::BLUE, base_color: BLUE,
emissive: Color::PINK, emissive: PINK.into(),
..Default::default() ..Default::default()
}), }),
..Default::default() ..Default::default()
@ -72,16 +69,10 @@ fn spawn_static_lights(
}) })
.with_children(|builder| { .with_children(|builder| {
builder.spawn(PbrBundle { builder.spawn(PbrBundle {
mesh: meshes.add( mesh: meshes.add(Mesh::from(Sphere::new(10.0))),
Mesh::try_from(shape::Icosphere {
radius: 10.0,
subdivisions: 2,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::PINK, base_color: PINK,
emissive: Color::BLUE, emissive: BLUE.into(),
..Default::default() ..Default::default()
}), }),
..Default::default() ..Default::default()
@ -92,6 +83,6 @@ fn spawn_static_lights(
pub struct CyberSpaceLightsPlugin; pub struct CyberSpaceLightsPlugin;
impl Plugin for CyberSpaceLightsPlugin { impl Plugin for CyberSpaceLightsPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_startup_system(spawn_static_lights); app.add_systems(Startup, spawn_static_lights);
} }
} }

View file

@ -8,7 +8,7 @@ use cyber_rider::{
}; };
//const CYBER_SKY: Color = Color::rgb(0.07, 0.001, 0.02); //const CYBER_SKY: Color = Color::rgb(0.07, 0.001, 0.02);
const CYBER_SKY: Color = Color::rgb(0.64, 0.745, 0.937); // a light blue sky const CYBER_SKY: Color = Color::srgb(0.64, 0.745, 0.937); // a light blue sky
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
@ -21,18 +21,36 @@ fn main() {
}), }),
..Default::default() ..Default::default()
})) }))
.add_plugin(CyberPlanetPlugin) .add_plugins((
.add_plugin(CyberInputPlugin) CyberPlanetPlugin,
.add_plugin(CyberActionPlugin) CyberInputPlugin,
.add_plugin(CyberCamPlugin) CyberActionPlugin,
.add_plugin(CyberSpaceLightsPlugin) CyberCamPlugin,
.add_plugin(CyberUIPlugin) CyberSpaceLightsPlugin,
.add_plugin(CyberBikePlugin) CyberUIPlugin,
.add_startup_system(disable_mouse_trap) CyberBikePlugin,
.add_system(bevy::window::close_on_esc); ))
.add_systems(Startup, disable_mouse_trap)
.add_systems(Update, close_on_esc);
#[cfg(feature = "inspector")] #[cfg(feature = "inspector")]
app.add_plugin(CyberGlamorPlugin); app.add_plugin(CyberGlamorPlugin);
app.run(); app.run();
} }
fn close_on_esc(
mut commands: Commands,
focused_windows: Query<(Entity, &Window)>,
input: Res<ButtonInput<KeyCode>>,
) {
for (window, focus) in focused_windows.iter() {
if !focus.focused {
continue;
}
if input.just_pressed(KeyCode::Escape) {
commands.entity(window).despawn();
}
}
}