Path: blob/main/crates/bevy_scene/src/scene_component.rs
30635 views
use bevy_ecs::{component::Component, reflect::ReflectComponent, template::FromTemplate};1use bevy_reflect::Reflect;23use crate::Scene;45/// Implemented for [`Component`]s that have an associated [`Scene`], which can be constructed6/// with [`Self::Props`].7///8/// In general, developers should not implement this manually. Instead, they should derive it,9/// which also derives [`Component`] and adds additional protections and assurances.10///11/// See the ["Scene Components"](crate#scene-components) section of the module docs to see how this is used in practice.12pub trait SceneComponent: Component + FromTemplate<Template: Default> {13/// The "properties" passed into [`Self::scene`] to build the final scene.14type Props: Default;1516/// A function that uses the given `props` to produce a [`Scene`]17fn scene(props: Self::Props) -> impl Scene;18}1920/// Indicates that this entity includes a [`Component`] that must always be spawned with a [`Scene`].21#[derive(Component, Default, Clone, Debug, Reflect)]22#[cfg_attr(debug_assertions, component(on_add))]23#[reflect(Component)]24pub struct SceneComponentInfo {25spawned_from_scene: bool,26#[cfg(debug_assertions)]27component_name: &'static str,28}2930impl SceneComponentInfo {31/// Creates a new [`SceneComponentInfo`] for the given type `C`.32pub fn new<C: Component>(spawned_from_scene: bool) -> Self {33SceneComponentInfo {34spawned_from_scene,35#[cfg(debug_assertions)]36component_name: core::any::type_name::<C>(),37}38}39}4041impl SceneComponentInfo {42#[cfg(debug_assertions)]43fn on_add(world: bevy_ecs::world::DeferredWorld, context: bevy_ecs::lifecycle::HookContext) {44if let Ok(entity) = world.get_entity(context.entity)45&& let Some(component) = entity.get::<SceneComponentInfo>()46&& !component.spawned_from_scene47{48tracing::error!(49"Entity {} was spawned with the \"scene component\" {}, but without its scene. \50Scene components should not be spawned directly as components. Instead, they \51should be spawned as \"scenes\" using world.spawn_scene or commands.spawn_scene. \52Scene components should be included using `@{}` syntax in BSN.",53context.entity,54component.component_name,55component.component_name56);57}58}59}606162