From f3b2139e9222ccd622a2ff1123868b85d649620e Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Fri, 21 Feb 2025 17:53:08 -0800 Subject: [PATCH] Only despawn scene entities still in the hierarchy (#17938) Fixes #17883 # Objective + Solution When doing normal scene root entity despawns (which are notably now recursive), do not despawn instanced entities that are no longer in the hierarchy. (I would not classify this as a bug, but rather a behavior change) ## Migration Guide If you previously relied on scene entities no longer in the hierarchy being despawned when the scene root is despawned , use `SceneSpawner::despawn_instance()` instead. --- crates/bevy_scene/src/lib.rs | 4 ++-- crates/bevy_scene/src/scene_spawner.rs | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index fe15866c14..f7d52e6b62 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -81,7 +81,7 @@ impl Plugin for ScenePlugin { if let Some(instance_ids) = scene_spawner.spawned_dynamic_scenes.get_mut(&id) { instance_ids.remove(&scene_instance); } - scene_spawner.despawn_instance(scene_instance); + scene_spawner.unregister_instance(scene_instance); } }); @@ -95,7 +95,7 @@ impl Plugin for ScenePlugin { let Some(mut scene_spawner) = world.get_resource_mut::() else { return; }; - scene_spawner.despawn_instance(scene_instance); + scene_spawner.unregister_instance(scene_instance); } }); } diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 3d4014f123..cf8195e676 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -179,10 +179,19 @@ impl SceneSpawner { } /// Schedule the despawn of a scene instance, removing all its entities from the world. + /// + /// Note: this will despawn _all_ entities associated with this instance, including those + /// that have been removed from the scene hierarchy. To despawn _only_ entities still in the hierarchy, + /// despawn the relevant root entity directly. pub fn despawn_instance(&mut self, instance_id: InstanceId) { self.instances_to_despawn.push(instance_id); } + /// This will remove all records of this instance, without despawning any entities. + pub fn unregister_instance(&mut self, instance_id: InstanceId) { + self.spawned_instances.remove(&instance_id); + } + /// Immediately despawns all instances of a dynamic scene. pub fn despawn_sync( &mut self,