diff --git a/src/bin/flappy/main.rs b/src/bin/flappy/main.rs index 601b565..5332512 100644 --- a/src/bin/flappy/main.rs +++ b/src/bin/flappy/main.rs @@ -15,7 +15,7 @@ fn main() { title: "flappy bird (with rewind)".into(), name: "flappy".into(), game_type: GameType::Two, - target_resolution: (360.0, 640.0).into(), + target_resolution: (360, 640).into(), ..default() }, Physics2dPlugin, @@ -99,8 +99,8 @@ fn main() { (update_tooltip, debug_trail).run_if(in_state(DebuggingState::On)), // TODO: Add run_if to this system update_batch_position.run_if(any_component_changed::), - move_batches.run_if(on_message::.or(on_message::)), - manage_score.run_if(on_message::.or(on_message::)), + move_batches.run_if(on_message::.or(on_message::)), + manage_score.run_if(on_message::.or(on_message::)), shimmer_button::.run_if(in_state(PlayerState::Stasis)), shimmer_button::.run_if(in_state(PlayerState::Pause)), ), @@ -142,7 +142,7 @@ struct Tape { capacity: usize, linear_velocities: VecDeque, angular_velocities: VecDeque, - external_impulses: VecDeque, + constant_forces: VecDeque, positions: VecDeque, rotations: VecDeque, } @@ -153,7 +153,7 @@ impl Tape { capacity, linear_velocities: VecDeque::with_capacity(capacity), angular_velocities: VecDeque::with_capacity(capacity), - external_impulses: VecDeque::with_capacity(capacity), + constant_forces: VecDeque::with_capacity(capacity), positions: VecDeque::with_capacity(capacity), rotations: VecDeque::with_capacity(capacity), } @@ -163,7 +163,7 @@ impl Tape { &mut self, lv: LinearVelocity, av: AngularVelocity, - ei: ExternalImpulse, + ei: ConstantForce, p: Position, r: Rotation, ) { @@ -171,14 +171,14 @@ impl Tape { if self.linear_velocities.len() == self.capacity { self.linear_velocities.pop_front().unwrap(); self.angular_velocities.pop_front().unwrap(); - self.external_impulses.pop_front().unwrap(); + self.constant_forces.pop_front().unwrap(); self.positions.pop_front().unwrap(); self.rotations.pop_front().unwrap(); } self.linear_velocities.push_back(lv); self.angular_velocities.push_back(av); - self.external_impulses.push_back(ei); + self.constant_forces.push_back(ei); self.positions.push_back(p); self.rotations.push_back(r); } @@ -188,7 +188,7 @@ impl Tape { ) -> Option<( LinearVelocity, AngularVelocity, - ExternalImpulse, + ConstantForce, Position, Rotation, )> { @@ -197,10 +197,10 @@ impl Tape { } else { let lv = self.linear_velocities.pop_back().unwrap(); let av = self.angular_velocities.pop_back().unwrap(); - let ei = self.external_impulses.pop_back().unwrap(); + let cf = self.constant_forces.pop_back().unwrap(); let p = self.positions.pop_back().unwrap(); let r = self.rotations.pop_back().unwrap(); - Some((lv, av, ei, p, r)) + Some((lv, av, cf, p, r)) } } } @@ -214,7 +214,7 @@ fn init_bird(mut commands: Commands, bird_assets: Res) { RigidBody::Static, Collider::rectangle(1.0, 1.0), Mass(10.0), - ExternalImpulse::default().with_persistence(false), + ConstantForce::default(), MaxLinearSpeed(500.0), ); @@ -349,7 +349,7 @@ fn populate_ceiling( } fn move_pipe( - event: On, + event: On, mut pipes: Query<(&Batch, &Pipe, &mut Transform)>, rand: Res, ) { @@ -524,42 +524,42 @@ fn init_ui(mut commands: Commands, server: Res) { parent.spawn(( Text::new("Game Over...?"), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent.spawn(( Text::new("Press R to Rewind"), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )); parent .spawn((Node { @@ -589,7 +589,7 @@ fn init_ui(mut commands: Commands, server: Res) { { fn quit_game( _event: On>, - mut exit: EventWriter, + mut exit: MessageWriter, ) { warn!("Quitting game"); exit.write(AppExit::Success); @@ -629,7 +629,7 @@ fn init_ui(mut commands: Commands, server: Res) { children![( Text::new(credits_str), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center) + TextLayout::new_with_justify(Justify::Center) )], )) .with_children(|parent| { @@ -734,7 +734,7 @@ fn init_ui(mut commands: Commands, server: Res) { Text::new("Rewind!\n(Hold R)"), TextColor(BLACK.into()), TextFont::from_font_size(20.0), - TextLayout::new_with_justify(JustifyText::Center) + TextLayout::new_with_justify(Justify::Center) ), ], )) @@ -766,7 +766,7 @@ fn init_ui(mut commands: Commands, server: Res) { Text::new("Flap!\n(Spacebar)"), TextColor(BLACK.into()), TextFont::from_font_size(20.0), - TextLayout::new_with_justify(JustifyText::Center) + TextLayout::new_with_justify(Justify::Center) ), ( ImageNode { @@ -797,7 +797,7 @@ fn init_ui(mut commands: Commands, server: Res) { SyncResource::::default(), Text::default(), TextColor(BLACK.into()), - TextLayout::new_with_justify(JustifyText::Center), + TextLayout::new_with_justify(Justify::Center), )], )); } @@ -845,16 +845,16 @@ fn init_background( } } -fn start_rewind(_event: On>, mut next: ResMut>) { +fn start_rewind(_event: On>, mut next: ResMut>) { next.set(PlayerState::Rewind); } -fn end_rewind(_event: On>, mut next: ResMut>) { +fn end_rewind(_event: On>, mut next: ResMut>) { next.set(PlayerState::Alive); } fn flap_button( - _event: On>, + _event: On>, mut commands: Commands, bird: Single>, curr: Res>, @@ -865,7 +865,7 @@ fn flap_button( } let e = *bird; debug!("Flapping {:?}", e); - commands.event_targets(Flap, e); + commands.trigger(Flap { entity: e }); } /// Pause the game when the player presses "Escape" @@ -877,13 +877,15 @@ fn un_pause_game(mut next: ResMut>) { next.set(PlayerState::Alive); } -#[derive(Component, Clone, Message)] -struct Flap; +#[derive(Component, Clone, Message, EntityEvent)] +struct Flap { + entity: Entity +} // Observer for flapping fn flap( event: On, - mut bird: Query<&mut ExternalImpulse, With>, + mut bird: Query>, mut flaps: ResMut, ) { debug!("real flap for {:?}", event.entity); @@ -892,7 +894,7 @@ fn flap( // Flap birds wings if let Ok(mut f) = bird.get_mut(event.entity) { - f.apply_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0); + f.apply_local_linear_impulse(Vec2::Y * 5000.0 + Vec2::X * 1000.0); } } @@ -916,7 +918,7 @@ fn flap_kb( birds.iter().for_each(|e| { debug!("Flapping {:?}", e); - commands.event_targets(Flap, e); + commands.trigger(Flap { entity: e }); }); } @@ -941,7 +943,7 @@ fn record( ( &LinearVelocity, &AngularVelocity, - &ExternalImpulse, + &ConstantForce, &Position, &Rotation, &mut Tape, @@ -956,7 +958,7 @@ fn record( ); birds.iter_mut().for_each(|(lv, av, ei, p, r, mut tape)| { - tape.push(*lv, *av, *ei, *p, *r); + tape.push(*lv, *av, ei.clone(), *p, *r); }); } @@ -967,7 +969,7 @@ fn rewind( ( &mut LinearVelocity, &mut AngularVelocity, - &mut ExternalImpulse, + // TODO: Need to re-add impulse here &mut Position, &mut Rotation, &mut Tape, @@ -984,11 +986,11 @@ fn rewind( birds .iter_mut() - .for_each(|(mut lv, mut av, mut ei, mut p, mut r, mut tape)| { - if let Some((new_lv, new_av, new_ei, new_p, new_r)) = tape.pop() { + .for_each(|(mut lv, mut av, mut p, mut r, mut tape)| { + if let Some((new_lv, new_av, _new_ei, new_p, new_r)) = tape.pop() { lv.0 = new_lv.0; av.0 = new_av.0; - ei.set_impulse(new_ei.impulse()); + // TODO: Need to re-add impulse here p.0 = new_p.0; *r = new_r; frames.0 += 1; @@ -1016,15 +1018,16 @@ fn detect_dead( } } -fn alive_bird(mut bird: Single<&mut RigidBody, With>) { +fn alive_bird(bird: Single>, mut commands: Commands) { debug!("Setting bird to Dynamic"); - **bird = RigidBody::Dynamic; + commands.entity(*bird).remove::(); } fn pause_bird( state: Res>, - mut bird: Single<&mut RigidBody, With>, + bird: Single>, mut deaths: ResMut, + mut commands: Commands, ) { // Increment death count if state.get() == &PlayerState::Stasis { @@ -1032,7 +1035,7 @@ fn pause_bird( } debug!("Setting bird to Static"); - **bird = RigidBody::Static; + commands.entity(*bird).insert(RigidBodyDisabled); } fn camera_follow_bird( @@ -1138,32 +1141,32 @@ impl Display for Deaths { } fn manage_score( - mut start: MessageReader, - mut end: MessageReader, + mut start: MessageReader, + mut end: MessageReader, state: Res>, hitboxes: Query<&Batch, With>, mut score: ResMut, ) { match state.get() { PlayerState::Rewind => { - start.read().for_each(|CollisionStarted(a, b)| { + start.read().for_each(|CollisionStart { collider1, collider2, .. }| { // Set score to collided hitbox - if let Ok(Batch(this)) = hitboxes.get(*a) { + if let Ok(Batch(this)) = hitboxes.get(*collider1) { debug!("[Rewind] Setting score to {this}"); score.0 = this.saturating_sub(1); - } else if let Ok(Batch(this)) = hitboxes.get(*b) { + } else if let Ok(Batch(this)) = hitboxes.get(*collider2) { debug!("[Rewind] Setting score to {this}"); score.0 = this.saturating_sub(1); } }) } _ => { - end.read().for_each(|CollisionEnded(a, b)| { + end.read().for_each(|CollisionEnd { collider1, collider2, .. }| { // Set score to collided hitbox - if let Ok(Batch(this)) = hitboxes.get(*b) { + if let Ok(Batch(this)) = hitboxes.get(*collider2) { debug!("[Alive] Setting score to {this}"); score.0 = *this; - } else if let Ok(Batch(this)) = hitboxes.get(*a) { + } else if let Ok(Batch(this)) = hitboxes.get(*collider1) { debug!("[Alive] Setting score to {this}"); score.0 = *this; } @@ -1182,15 +1185,15 @@ fn manage_score( /// Finally we iterate over all entities with the old batch ID and upsert the new batch ID /// This includes root batch entities as well as pipes and hitboxes fn move_batches( - mut start: MessageReader, - mut end: MessageReader, + mut start: MessageReader, + mut end: MessageReader, hitboxes: Query>, batches: Query<(Entity, &Batch)>, state: Res>, mut commands: Commands, ) { - let s = start.read().map(|CollisionStarted(a, b)| (a, b)); - let e = end.read().map(|CollisionEnded(a, b)| (a, b)); + let s = start.read().map(|CollisionStart { collider1, collider2, .. }| (collider1, collider2)); + let e = end.read().map(|CollisionEnd { collider1, collider2, .. }| (collider1, collider2)); let c = s.chain(e); c.for_each(|(a, b)| { debug!("[batches] Collision {a} -> {b}"); diff --git a/src/bin/trees/debug.rs b/src/bin/trees/debug.rs index 09645d7..188bbdb 100644 --- a/src/bin/trees/debug.rs +++ b/src/bin/trees/debug.rs @@ -44,7 +44,7 @@ fn drag_tree( debug_assert_eq!(*state.get(), DebuggingState::On); events.read().for_each(|event| { - if let Ok(mut t) = query.get_mut(event.target) { + if let Ok(mut t) = query.get_mut(event.entity) { let world_position = window .cursor_position() .and_then(|cursor| camera.0.viewport_to_world(camera.1, cursor).ok()) @@ -164,7 +164,7 @@ fn control_menu( hover_map: Res, ) { over_events.read().for_each(|over| { - let root = nav_children.root_ancestor(over.target); + let root = nav_children.root_ancestor(over.entity); nav_parents.iter_descendants(root).for_each(|child| { if let Ok(mut n) = nav.get_mut(child) { @@ -184,9 +184,9 @@ fn control_menu( // For all pointer out events out_events.read().for_each(|out| { - // If a relative of out.target is hovered, do nothing + // If a relative of out.entity is hovered, do nothing // Otherwise set to closed - let root = children.root_ancestor(out.target); + let root = children.root_ancestor(out.entity); let tree_still_hovered = parents .iter_descendants(root) .any(|child| is_hovered.contains(&&child)); @@ -215,7 +215,7 @@ fn add_dialog_option(event: On, mut commands: Commands) { width: Val::Percent(100.0), ..default() }) - .insert(TextLayout::new_with_justify(JustifyText::Center)) + .insert(TextLayout::new_with_justify(Justify::Center)) .insert(TextColor(ORANGE.into())) .observe(choose_dialog_option) .observe(hover_dialog_option_over) @@ -224,7 +224,7 @@ fn add_dialog_option(event: On, mut commands: Commands) { fn assign_monologue_event( event: On>, - mut events: EventWriter, + mut events: MessageWriter, monologues: Query<&TreeMonologue>, ) { let TreeMonologue(handle) = monologues.get(event.entity).unwrap(); @@ -232,7 +232,7 @@ fn assign_monologue_event( } /// Observer for the "Plant a new tree" button in the debug UI -fn spawn_tree(_event: On>, mut events: EventWriter) { +fn spawn_tree(_event: On>, mut events: MessageWriter) { events.write(PlantTree(None)); } @@ -266,9 +266,9 @@ fn delete_tree( query: Query>, ) { events.read().for_each(|event| { - if matches!(event.event.button, PointerButton::Middle) && query.contains(event.target) { - debug!("Middle Click -> Despawning {}", event.target); - commands.entity(event.target).despawn(); + if matches!(event.event.button, PointerButton::Middle) && query.contains(event.entity) { + debug!("Middle Click -> Despawning {}", event.entity); + commands.entity(event.entity).despawn(); } }) } @@ -291,10 +291,12 @@ fn monologue_asset_tooltip( .read() .filter_map(|Pointer { entity, .. }| trees.contains(*entity).then_some(*entity)) .for_each(|e| match trees.get(e) { - Ok((_tree, Some(TreeMonologue(handle)))) => match handle.path() { - Some(p) => tooltip.insert("Script", format!("{p}")), - None => tooltip.insert("Script", "A".into()), - }, + Ok((_tree, Some(TreeMonologue(id)))) => { + match todo!("Get path for this asset") { + Some(p) => tooltip.insert("Script", format!("{p}")), + None => tooltip.insert("Script", "A".into()), + } + } Ok((_tree, None)) => { tooltip.insert("Script", "N/A".into()); } @@ -305,7 +307,7 @@ fn monologue_asset_tooltip( /// When a dialog option is chosen (clicked on) we do the following: fn choose_dialog_option( event: On>, - mut dialog_events: EventWriter, + mut dialog_events: MessageWriter, mut commands: Commands, texts: Query<&Text>, options: Query>, @@ -337,9 +339,9 @@ fn preview_monologue( mut commands: Commands, ) { // Get the handle for this button's monologuie - if let Ok(TreeMonologue(handle)) = tree_monologue.get(event.entity) { + if let Ok(TreeMonologue(id)) = tree_monologue.get(event.entity) { // Get the monologue data - if let Some(monologue) = monologues.get(handle) { + if let Some(monologue) = monologues.get(*id) { commands.entity(*container).despawn_related::(); // Spawn the monologue @@ -396,9 +398,9 @@ fn spawn_debug_buttons( .trim_prefix("trees/") .trim_suffix(".mono"), ), - TextLayout::new(JustifyText::Left, LineBreak::WordBoundary), + TextLayout::new(Justify::Left, LineBreak::WordBoundary), ], - TreeMonologue(handle.clone()), + TreeMonologue(handle.id()), MonologuesList, )) .observe(assign_monologue_event) diff --git a/src/bin/trees/main.rs b/src/bin/trees/main.rs index c34cbaa..c5e7153 100644 --- a/src/bin/trees/main.rs +++ b/src/bin/trees/main.rs @@ -20,9 +20,9 @@ fn main() { }) .add_plugins(MonologueAssetsPlugin) .add_plugins(TreesDebugPlugin) - .add_event::() - .add_event::() - .add_event::() + .add_message::() + .add_message::() + .add_message::() .init_state::() .insert_resource(ClearColor(WHITE.into())) .add_systems( @@ -69,7 +69,7 @@ fn main() { struct Tree; #[derive(Component, PartialEq, Clone)] -struct TreeMonologue(Handle); +struct TreeMonologue(AssetId); /// Initialize the trees, currently placeholders /// Trees are 2d cards in a 3d world for flexibility @@ -149,7 +149,7 @@ fn auto_scroll( ); scroll_positions.iter_mut().for_each(|mut sp| { - sp.offset_y = f32::MAX; + sp.y = f32::MAX; }); } @@ -164,7 +164,7 @@ struct DialogLine; /// Events that drive the dialog engine #[derive(Message, PartialEq)] enum DialogEvent { - Start(Entity, Handle), + Start(Entity, AssetId), NextBatch, End, } @@ -184,14 +184,14 @@ enum DialogState { /// Start dialog fn start_dialog( mut click_events: MessageReader>, - mut dialog_events: EventWriter, + mut dialog_events: MessageWriter, query: Query<&TreeMonologue, With>, ) { click_events.read().for_each(|event| { debug!("Click event detected in start dialog systme"); - if let Ok(TreeMonologue(handle)) = query.get(event.target) { + if let Ok(TreeMonologue(id)) = query.get(event.entity) { debug!("Tree Monologue received, sending start dialog event"); - dialog_events.write(DialogEvent::Start(event.target, handle.clone())); + dialog_events.write(DialogEvent::Start(event.entity, id.clone())); dialog_events.write(DialogEvent::NextBatch); } }) @@ -200,12 +200,12 @@ fn start_dialog( /// When dialog is complete and you click away from the dialog box, close it out fn end_dialog( mut click_events: MessageReader>, - mut dialog_events: EventWriter, + mut dialog_events: MessageWriter, query: Query, With, With)>>, ) { click_events.read().for_each(|event| { - debug!("Click even evented end of dialog: {:?}", event.target); - if !query.contains(event.target) { + debug!("Click even evented end of dialog: {:?}", event.entity); + if !query.contains(event.entity) { dialog_events.write(DialogEvent::End); } }); @@ -220,7 +220,7 @@ fn dialog_engine( // EntityCommands for Dialog Box mut commands: Commands, // Handle to "active" monologue - mut handle: Local>, + mut asset_id: Local>, // Track active entity as well as the monologue mut tree_entity: Local>, // Index into "active" monologue @@ -239,14 +239,14 @@ fn dialog_engine( events.read().for_each(|event| { match event { - DialogEvent::Start(e, h) => { - debug!("Dialog start: {:?}", h); + DialogEvent::Start(e, id) => { + debug!("Dialog start: {:?}", id); // Set state to "Active" next_state.set(DialogState::Ongoing); // Copy monologue asset into local - *handle = h.clone(); + *asset_id = id.clone(); *tree_entity = Some(*e); } DialogEvent::NextBatch => { @@ -254,7 +254,7 @@ fn dialog_engine( commands.entity(*dialog_box).with_children(|parent| { // Fetch this monologue from the assets - if let Some(monologue) = monologues.get(handle.clone().id()) { + if let Some(monologue) = monologues.get(asset_id.clone()) { // Fetch this batch of options if let Some(batch) = monologue.get(*idx) { // Spawn the dialog options in the dialog box @@ -262,7 +262,7 @@ fn dialog_engine( parent.spawn(( Text::new(line.clone()), DialogOption, - TextLayout::new(JustifyText::Left, LineBreak::NoWrap), + TextLayout::new(Justify::Left, LineBreak::NoWrap), )); }); *idx += 1; @@ -290,7 +290,7 @@ fn dialog_engine( *idx = 0; // Wipe the current handle from context - *handle = Handle::default(); + *asset_id = AssetId::default(); // Set state to "Active" next_state.set(DialogState::None); @@ -389,21 +389,21 @@ fn scale_window(events: MessageReader, mut window: Single<&mut Wi } /// Load all monologues so they are in the asset store and event on-load events -fn load_monologues(server: ResMut, mut loaded_assets: Local>>) { +fn load_monologues(server: ResMut, mut loaded_assets: Local>>) { *loaded_assets = include_str!("../../../assets/trees/MONOLOGUES") .split("\n") - .map(|path| server.load(path)) + .map(|path| server.load(path).id()) .collect(); } #[derive(Message)] -struct PlantTree(Option>); +struct PlantTree(Option>); /// Plan a tree in the world /// Handles random placement, 3d model, materials, and observers fn handle_plant_tree( mut events: MessageReader, - mut assignments: EventWriter, + mut assignments: MessageWriter, trees: Query>, server: Res, mut commands: Commands, @@ -442,14 +442,14 @@ fn handle_plant_tree( tree.insert((mesh, material, transform)); - if let Some(handle) = assignment { - assignments.write(AssignMonologue(handle.clone())); + if let Some(id) = assignment { + assignments.write(AssignMonologue(id.clone())); } }); } #[derive(Message, Debug)] -struct AssignMonologue(Handle); +struct AssignMonologue(AssetId); /// Assign the given monologue to a tree fn assign_monologue_to_tree( @@ -470,7 +470,7 @@ fn assign_monologue_to_tree( let monologue = TreeMonologue(event.0.clone()); // Insert the component to the entity commands.entity(tree).insert(monologue); - } else if let Some(path) = event.0.path() { + } else if let Some(path) = todo!("event.0.path() -> assetId") { error!("No trees avaliable for {path:?}"); notice.0 = format!("No trees avaliable for {path:?}"); } else { @@ -481,12 +481,12 @@ fn assign_monologue_to_tree( } /// On startup, plant a forest (add a few trees to the game) -fn plant_forest(monos: Res>, mut e_trees: EventWriter) { +fn plant_forest(monos: Res>, mut e_trees: MessageWriter) { let mut i = 10; for id in monos.ids() { debug!("Planting tree with monologue {:?}", id); if i > 5 { - e_trees.write(PlantTree(Some(Handle::Weak(id)))); + e_trees.write(PlantTree(Some(id))); } else if i > 0 { e_trees.write(PlantTree(None)); } else { diff --git a/src/lib.rs b/src/lib.rs index c3728a2..42d78f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ pub use std::fmt::Display; // Community libraries pub use bevy::{ - asset::{AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, io::Reader, RenderAssetUsages}, + asset::{AssetLoader, AssetMetaCheck, LoadContext, LoadState, LoadedFolder, io::Reader, RenderAssetUsages, uuid_handle}, math::{FloatOrd}, camera::{*, primitives::*, visibility::*}, color::palettes::css::*, diff --git a/src/physics3d.rs b/src/physics3d.rs index ff7a2c4..0b43791 100644 --- a/src/physics3d.rs +++ b/src/physics3d.rs @@ -6,7 +6,7 @@ pub struct Physics3dPlugin; impl Plugin for Physics3dPlugin { fn build(&self, app: &mut App) { - app.add_plugins((PhysicsDebugPlugin::default(), PhysicsPlugins::default())) + app.add_plugins((PhysicsDebugPlugin, PhysicsPlugins::default())) .add_systems( Update, toggle_physics_debug_render.run_if(state_changed::),