diff --git a/bevy_rapier2d/examples/despawn2.rs b/bevy_rapier2d/examples/despawn2.rs index 3024fcb91fcd9..79b04073ed40b 100644 --- a/bevy_rapier2d/examples/despawn2.rs +++ b/bevy_rapier2d/examples/despawn2.rs @@ -17,6 +17,11 @@ pub struct DespawnResource { pub entities: Vec, } +#[derive(Default)] +pub struct ResizeResource { + pub entities: Vec, +} + fn main() { App::build() .add_resource(ClearColor(Color::rgb( @@ -26,6 +31,7 @@ fn main() { ))) .add_resource(Msaa::default()) .add_resource(DespawnResource::default()) + .add_resource(ResizeResource::default()) .add_plugins(DefaultPlugins) .add_plugin(bevy_winit::WinitPlugin::default()) .add_plugin(bevy_wgpu::WgpuPlugin::default()) @@ -36,6 +42,7 @@ fn main() { .add_startup_system(setup_physics.system()) .add_startup_system(enable_physics_profiling.system()) .add_system(despawn.system()) + .add_system(resize.system()) .run(); } @@ -57,7 +64,11 @@ fn setup_graphics(commands: &mut Commands, mut configuration: ResMut) { +pub fn setup_physics( + commands: &mut Commands, + mut despawn: ResMut, + mut resize: ResMut, +) { /* * Ground */ @@ -107,6 +118,9 @@ pub fn setup_physics(commands: &mut Commands, mut despawn: ResMut, mut despawn: ResMut, mut resize: ResMut) { + if time.seconds_since_startup() > 6.0 { + for entity in &resize.entities { + println!("Resizing a block"); + let collider = ColliderBuilder::cuboid(4.0, 4.0).density(1.0); + commands.insert_one(*entity, collider); + } + resize.entities.clear(); + } +} diff --git a/src/physics/plugins.rs b/src/physics/plugins.rs index de6b110697d5b..89b0f5920a852 100644 --- a/src/physics/plugins.rs +++ b/src/physics/plugins.rs @@ -47,6 +47,7 @@ impl Plugin for RapierPhysicsPlugin { stage::PRE_UPDATE, physics::create_body_and_collider_system.system(), ) + .add_system_to_stage(stage::PRE_UPDATE, physics::update_collider_system.system()) .add_system_to_stage(stage::PRE_UPDATE, physics::create_joints_system.system()) .add_system_to_stage(stage::UPDATE, physics::step_world_system.system()) .add_stage_before( diff --git a/src/physics/systems.rs b/src/physics/systems.rs index c573417eeca55..09805c6734753 100644 --- a/src/physics/systems.rs +++ b/src/physics/systems.rs @@ -51,6 +51,45 @@ pub fn create_body_and_collider_system( } } +/// System responsible for replacing colliders on existing bodies when a new +/// builder is added. +/// +/// NOTE: This only adds new colliders, the old collider is actually removed +/// by `destroy_body_and_collider_system` +pub fn update_collider_system( + commands: &mut Commands, + mut bodies: ResMut, + mut colliders: ResMut, + mut entity_maps: ResMut, + with_body_query: Query< + (Entity, &RigidBodyHandleComponent, &ColliderBuilder), + With, + >, + without_body_query: Query< + (Entity, &Parent, &ColliderBuilder), + ( + Without, + With, + ), + >, +) { + for (entity, body_handle, collider_builder) in with_body_query.iter() { + let handle = colliders.insert(collider_builder.build(), body_handle.handle(), &mut bodies); + commands.insert_one(entity, ColliderHandleComponent::from(handle)); + commands.remove_one::(entity); + entity_maps.colliders.insert(entity, handle); + } + + for (entity, parent, collider_builder) in without_body_query.iter() { + if let Some(body_handle) = entity_maps.bodies.get(&parent.0) { + let handle = colliders.insert(collider_builder.build(), *body_handle, &mut bodies); + commands.insert_one(entity, ColliderHandleComponent::from(handle)); + commands.remove_one::(entity); + entity_maps.colliders.insert(entity, handle); + } + } +} + #[test] fn test_create_body_and_collider_system() { use bevy::ecs::Schedule; diff --git a/src/render/systems.rs b/src/render/systems.rs index 0052287c99972..8b7589326cf7d 100644 --- a/src/render/systems.rs +++ b/src/render/systems.rs @@ -16,7 +16,7 @@ pub fn create_collider_renders_system( colliders: ResMut, query: Query< (Entity, &ColliderHandleComponent, Option<&RapierRenderColor>), - Without>, + Or<(Without>, Changed)>, >, ) { let ground_color = Color::rgb(