diff --git a/crates/bevy_scene/src/spawn.rs b/crates/bevy_scene/src/spawn.rs index efb4d94fbc26e..eac85b446d383 100644 --- a/crates/bevy_scene/src/spawn.rs +++ b/crates/bevy_scene/src/spawn.rs @@ -196,7 +196,13 @@ impl WorldSceneExt for World { let assets = self.resource::(); let patch = ScenePatch::load(assets, scene); let handle = assets.add(patch); - self.spawn(ScenePatchInstance(handle)) + let mut entity = self.spawn_empty(); + let id = entity.id(); + entity + .resource_mut::() + .new_scene_entities + .push((id, handle)); + entity } fn spawn_scene_list( @@ -501,7 +507,10 @@ impl EntityWorldMutSceneExt for EntityWorldMut<'_> { let assets = self.resource::(); let patch = ScenePatch::load(assets, scene); let handle = assets.add(patch); - self.insert(ScenePatchInstance(handle)); + let id = self.id(); + self.resource_mut::() + .new_scene_entities + .push((id, handle)); } } @@ -660,7 +669,7 @@ pub fn resolve_scene_patches( /// A [`Resource`] that tracks entities / scenes that have been queued to spawn. #[derive(Resource, Default)] pub struct QueuedScenes { - new_scene_entities: Vec, + new_scene_entities: Vec<(Entity, Handle)>, related_scene_list_spawns: Vec<(RelatedSceneListSpawn, Handle)>, scene_list_spawns: Vec>, } @@ -682,8 +691,13 @@ pub(crate) struct RelatedSceneListSpawn { pub fn on_add_scene_patch_instance( add: On, mut queued_scenes: ResMut, + instances: Query<&ScenePatchInstance>, ) { - queued_scenes.new_scene_entities.push(add.entity); + if let Ok(instance) = instances.get(add.entity) { + queued_scenes + .new_scene_entities + .push((add.entity, instance.0.clone())); + } } /// A system that spawns queued scenes when they are loaded. @@ -695,22 +709,8 @@ pub fn spawn_queued( mut reader: Local>>, mut list_reader: Local>>, ) { - core::mem::swap(&mut *world.resource_mut::(), &mut queued); world.resource_scope(|world, mut list_patches: Mut>| { world.resource_scope(|world, mut waiting: Mut| { - loop { - if queued.is_empty() { - break; - } - queued.spawn_queued( - world, - &mut waiting, - scene_patch_instances, - &mut bundle_scratch, - &list_patches, - ); - } - world.resource_scope(|world, events: Mut>>| { for event in reader.read(&events) { let patches = world.resource::>(); @@ -765,6 +765,20 @@ pub fn spawn_queued( } }, ); + + loop { + core::mem::swap(&mut *world.resource_mut::(), &mut queued); + if queued.is_empty() { + break; + } + queued.spawn_queued( + world, + &mut waiting, + scene_patch_instances, + &mut bundle_scratch, + &list_patches, + ); + } }); }); } @@ -784,12 +798,9 @@ impl QueuedScenes { bundle_scratch: &mut BundleScratch, list_patches: &Assets, ) { - for entity in core::mem::take(&mut self.new_scene_entities) { - let Ok(handle) = scene_patch_instances.get(world, entity).map(|h| &h.0) else { - continue; - }; + for (entity, handle) in core::mem::take(&mut self.new_scene_entities) { let patches = world.resource::>(); - if let Some(resolved) = patches.get(handle).and_then(|p| p.resolved.clone()) { + if let Some(resolved) = patches.get(&handle).and_then(|p| p.resolved.clone()) { let mut entity_mut = world.get_entity_mut(entity).unwrap(); if let Err(err) = resolved.apply(&mut entity_mut, bundle_scratch) { let scene_patch_instance = scene_patch_instances.get(world, entity).unwrap();