bevy_scene/
lib.rs

1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![forbid(unsafe_code)]
3#![doc(
4    html_logo_url = "https://bevyengine.org/assets/icon.png",
5    html_favicon_url = "https://bevyengine.org/assets/icon.png"
6)]
7
8//! Provides scene definition, instantiation and serialization/deserialization.
9//!
10//! Scenes are collections of entities and their associated components that can be
11//! instantiated or removed from a world to allow composition. Scenes can be serialized/deserialized,
12//! for example to save part of the world state to a file.
13
14extern crate alloc;
15
16mod bundle;
17mod components;
18mod dynamic_scene;
19mod dynamic_scene_builder;
20mod scene;
21mod scene_filter;
22mod scene_loader;
23mod scene_spawner;
24
25#[cfg(feature = "serialize")]
26pub mod serde;
27
28/// Rusty Object Notation, a crate used to serialize and deserialize bevy scenes.
29pub use bevy_asset::ron;
30
31use bevy_ecs::schedule::IntoSystemConfigs;
32pub use bundle::*;
33pub use components::*;
34pub use dynamic_scene::*;
35pub use dynamic_scene_builder::*;
36pub use scene::*;
37pub use scene_filter::*;
38pub use scene_loader::*;
39pub use scene_spawner::*;
40
41/// The scene prelude.
42///
43/// This includes the most common types in this crate, re-exported for your convenience.
44#[expect(deprecated)]
45pub mod prelude {
46    #[doc(hidden)]
47    pub use crate::{
48        DynamicScene, DynamicSceneBuilder, DynamicSceneBundle, DynamicSceneRoot, Scene,
49        SceneBundle, SceneFilter, SceneRoot, SceneSpawner,
50    };
51}
52
53use bevy_app::prelude::*;
54use bevy_asset::AssetApp;
55
56/// Plugin that provides scene functionality to an [`App`].
57#[derive(Default)]
58pub struct ScenePlugin;
59
60#[cfg(feature = "serialize")]
61impl Plugin for ScenePlugin {
62    fn build(&self, app: &mut App) {
63        app.init_asset::<DynamicScene>()
64            .init_asset::<Scene>()
65            .init_asset_loader::<SceneLoader>()
66            .init_resource::<SceneSpawner>()
67            .register_type::<SceneRoot>()
68            .register_type::<DynamicSceneRoot>()
69            .add_systems(SpawnScene, (scene_spawner, scene_spawner_system).chain());
70
71        // Register component hooks for DynamicSceneRoot
72        app.world_mut()
73            .register_component_hooks::<DynamicSceneRoot>()
74            .on_remove(|mut world, entity, _| {
75                let Some(handle) = world.get::<DynamicSceneRoot>(entity) else {
76                    return;
77                };
78                let id = handle.id();
79                if let Some(&SceneInstance(scene_instance)) = world.get::<SceneInstance>(entity) {
80                    let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
81                        return;
82                    };
83                    if let Some(instance_ids) = scene_spawner.spawned_dynamic_scenes.get_mut(&id) {
84                        instance_ids.remove(&scene_instance);
85                    }
86                    scene_spawner.despawn_instance(scene_instance);
87                }
88            });
89
90        // Register component hooks for SceneRoot
91        app.world_mut()
92            .register_component_hooks::<SceneRoot>()
93            .on_remove(|mut world, entity, _| {
94                if let Some(&SceneInstance(scene_instance)) = world.get::<SceneInstance>(entity) {
95                    let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
96                        return;
97                    };
98                    scene_spawner.despawn_instance(scene_instance);
99                }
100            });
101    }
102}
103
104#[cfg(not(feature = "serialize"))]
105impl Plugin for ScenePlugin {
106    fn build(&self, _: &mut App) {}
107}