Skip to content

Commit deba380

Browse files
authored
avoid panic with parented scenes on deleted entities (#8512)
# Objective after calling `SceneSpawner::spawn_as_child`, the scene spawner system will always try to attach the scene instance to the parent once it is loaded, even if the parent has been deleted, causing a panic. ## Solution check if the parent is still alive, and don't spawn the scene instance if not.
1 parent 55d6c7d commit deba380

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

crates/bevy_scene/src/scene_spawner.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bevy_ecs::{
88
world::{Mut, World},
99
};
1010
use bevy_hierarchy::{AddChild, Parent};
11-
use bevy_utils::{tracing::error, HashMap};
11+
use bevy_utils::{tracing::error, HashMap, HashSet};
1212
use thiserror::Error;
1313
use uuid::Uuid;
1414

@@ -316,6 +316,26 @@ impl SceneSpawner {
316316

317317
pub fn scene_spawner_system(world: &mut World) {
318318
world.resource_scope(|world, mut scene_spawner: Mut<SceneSpawner>| {
319+
// remove any loading instances where parent is deleted
320+
let mut dead_instances = HashSet::default();
321+
scene_spawner
322+
.scenes_with_parent
323+
.retain(|(instance, parent)| {
324+
let retain = world.get_entity(*parent).is_some();
325+
326+
if !retain {
327+
dead_instances.insert(*instance);
328+
}
329+
330+
retain
331+
});
332+
scene_spawner
333+
.dynamic_scenes_to_spawn
334+
.retain(|(_, instance)| !dead_instances.contains(instance));
335+
scene_spawner
336+
.scenes_to_spawn
337+
.retain(|(_, instance)| !dead_instances.contains(instance));
338+
319339
let scene_asset_events = world.resource::<Events<AssetEvent<DynamicScene>>>();
320340

321341
let mut updated_spawned_scenes = Vec::new();

0 commit comments

Comments
 (0)