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.
This commit is contained in:
robtfm 2023-05-01 16:33:42 +01:00 committed by GitHub
parent 55d6c7d56e
commit deba3806d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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;
@ -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();