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.
This commit is contained in:
Carter Anderson 2025-02-21 17:53:08 -08:00 committed by GitHub
parent 052b9d8261
commit f3b2139e92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 2 deletions

View File

@ -81,7 +81,7 @@ impl Plugin for ScenePlugin {
if let Some(instance_ids) = scene_spawner.spawned_dynamic_scenes.get_mut(&id) { if let Some(instance_ids) = scene_spawner.spawned_dynamic_scenes.get_mut(&id) {
instance_ids.remove(&scene_instance); 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::<SceneSpawner>() else { let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
return; return;
}; };
scene_spawner.despawn_instance(scene_instance); scene_spawner.unregister_instance(scene_instance);
} }
}); });
} }

View File

@ -179,10 +179,19 @@ impl SceneSpawner {
} }
/// Schedule the despawn of a scene instance, removing all its entities from the world. /// 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) { pub fn despawn_instance(&mut self, instance_id: InstanceId) {
self.instances_to_despawn.push(instance_id); 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. /// Immediately despawns all instances of a dynamic scene.
pub fn despawn_sync( pub fn despawn_sync(
&mut self, &mut self,