Skip to content

Commit

Permalink
avoid panic with parented scenes on deleted entities (#8512)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
robtfm authored May 1, 2023
1 parent 55d6c7d commit deba380
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion crates/bevy_scene/src/scene_spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bevy_ecs::{
world::{Mut, World},
};
use bevy_hierarchy::{AddChild, Parent};
use bevy_utils::{tracing::error, HashMap};
use bevy_utils::{tracing::error, HashMap, HashSet};
use thiserror::Error;
use uuid::Uuid;

Expand Down Expand Up @@ -316,6 +316,26 @@ impl SceneSpawner {

pub fn scene_spawner_system(world: &mut World) {
world.resource_scope(|world, mut scene_spawner: Mut<SceneSpawner>| {
// remove any loading instances where parent is deleted
let mut dead_instances = HashSet::default();
scene_spawner
.scenes_with_parent
.retain(|(instance, parent)| {
let retain = world.get_entity(*parent).is_some();

if !retain {
dead_instances.insert(*instance);
}

retain
});
scene_spawner
.dynamic_scenes_to_spawn
.retain(|(_, instance)| !dead_instances.contains(instance));
scene_spawner
.scenes_to_spawn
.retain(|(_, instance)| !dead_instances.contains(instance));

let scene_asset_events = world.resource::<Events<AssetEvent<DynamicScene>>>();

let mut updated_spawned_scenes = Vec::new();
Expand Down

0 comments on commit deba380

Please sign in to comment.