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:
parent
55d6c7d56e
commit
deba3806d6
@ -8,7 +8,7 @@ use bevy_ecs::{
|
|||||||
world::{Mut, World},
|
world::{Mut, World},
|
||||||
};
|
};
|
||||||
use bevy_hierarchy::{AddChild, Parent};
|
use bevy_hierarchy::{AddChild, Parent};
|
||||||
use bevy_utils::{tracing::error, HashMap};
|
use bevy_utils::{tracing::error, HashMap, HashSet};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -316,6 +316,26 @@ impl SceneSpawner {
|
|||||||
|
|
||||||
pub fn scene_spawner_system(world: &mut World) {
|
pub fn scene_spawner_system(world: &mut World) {
|
||||||
world.resource_scope(|world, mut scene_spawner: Mut<SceneSpawner>| {
|
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 scene_asset_events = world.resource::<Events<AssetEvent<DynamicScene>>>();
|
||||||
|
|
||||||
let mut updated_spawned_scenes = Vec::new();
|
let mut updated_spawned_scenes = Vec::new();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user