mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Migrate scenes to required components (#15579)
# Objective A step in the migration to required components: scenes! ## Solution As per the [selected proposal](https://hackmd.io/@bevy/required_components/%2FPJtNGVMMQhyM0zIvCJSkbA): - Deprecate `SceneBundle` and `DynamicSceneBundle`. - Add `SceneRoot` and `DynamicSceneRoot` components, which wrap a `Handle<Scene>` and `Handle<DynamicScene>` respectively. ## Migration Guide Asset handles for scenes and dynamic scenes must now be wrapped in the `SceneRoot` and `DynamicSceneRoot` components. Raw handles as components no longer spawn scenes. Additionally, `SceneBundle` and `DynamicSceneBundle` have been deprecated. Instead, use the scene components directly. Previously: ```rust let model_scene = asset_server.load(GltfAssetLabel::Scene(0).from_asset("model.gltf")); commands.spawn(SceneBundle { scene: model_scene, transform: Transform::from_xyz(-4.0, 0.0, -3.0), ..default() }); ``` Now: ```rust let model_scene = asset_server.load(GltfAssetLabel::Scene(0).from_asset("model.gltf")); commands.spawn(( SceneRoot(model_scene), Transform::from_xyz(-4.0, 0.0, -3.0), )); ```
This commit is contained in:
parent
ead84e0e3d
commit
eb51b4c28e
43 changed files with 272 additions and 309 deletions
|
@ -653,7 +653,7 @@ impl ActiveAnimation {
|
|||
|
||||
/// Animation controls.
|
||||
///
|
||||
/// Automatically added to any root animations of a `SceneBundle` when it is
|
||||
/// Automatically added to any root animations of a scene when it is
|
||||
/// spawned.
|
||||
#[derive(Component, Default, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
|
|
|
@ -22,15 +22,14 @@
|
|||
//! # use bevy_gltf::prelude::*;
|
||||
//!
|
||||
//! fn spawn_gltf(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
//! commands.spawn(SceneBundle {
|
||||
//! commands.spawn((
|
||||
//! // This is equivalent to "models/FlightHelmet/FlightHelmet.gltf#Scene0"
|
||||
//! // The `#Scene0` label here is very important because it tells bevy to load the first scene in the glTF file.
|
||||
//! // If this isn't specified bevy doesn't know which part of the glTF file to load.
|
||||
//! scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
//! SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"))),
|
||||
//! // You can use the transform to give it a position
|
||||
//! transform: Transform::from_xyz(2.0, 0.0, -5.0),
|
||||
//! ..Default::default()
|
||||
//! });
|
||||
//! Transform::from_xyz(2.0, 0.0, -5.0),
|
||||
//! ));
|
||||
//! }
|
||||
//! ```
|
||||
//! # Loading parts of a glTF asset
|
||||
|
@ -72,18 +71,14 @@
|
|||
//! };
|
||||
//! *loaded = true;
|
||||
//!
|
||||
//! commands.spawn(SceneBundle {
|
||||
//! // Gets the first scene in the file
|
||||
//! scene: gltf.scenes[0].clone(),
|
||||
//! ..Default::default()
|
||||
//! });
|
||||
//! // Spawns the first scene in the file
|
||||
//! commands.spawn(SceneRoot(gltf.scenes[0].clone()));
|
||||
//!
|
||||
//! commands.spawn(SceneBundle {
|
||||
//! // Gets the scene named "Lenses_low"
|
||||
//! scene: gltf.named_scenes["Lenses_low"].clone(),
|
||||
//! transform: Transform::from_xyz(1.0, 2.0, 3.0),
|
||||
//! ..Default::default()
|
||||
//! });
|
||||
//! // Spawns the scene named "Lenses_low"
|
||||
//! commands.spawn((
|
||||
//! SceneRoot(gltf.named_scenes["Lenses_low"].clone()),
|
||||
//! Transform::from_xyz(1.0, 2.0, 3.0),
|
||||
//! ));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use bevy_asset::Handle;
|
||||
#![expect(deprecated)]
|
||||
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::{
|
||||
bundle::Bundle,
|
||||
|
@ -11,21 +12,25 @@ use bevy_ecs::{
|
|||
use bevy_render::prelude::{InheritedVisibility, ViewVisibility, Visibility};
|
||||
use bevy_transform::components::{GlobalTransform, Transform};
|
||||
|
||||
use crate::{DynamicScene, InstanceId, Scene, SceneSpawner};
|
||||
use crate::{DynamicSceneRoot, InstanceId, SceneRoot, SceneSpawner};
|
||||
|
||||
/// [`InstanceId`] of a spawned scene. It can be used with the [`SceneSpawner`] to
|
||||
/// interact with the spawned scene.
|
||||
#[derive(Component, Deref, DerefMut)]
|
||||
pub struct SceneInstance(pub(crate) InstanceId);
|
||||
|
||||
/// A component bundle for a [`Scene`] root.
|
||||
/// A component bundle for a [`Scene`](crate::Scene) root.
|
||||
///
|
||||
/// The scene from `scene` will be spawned as a child of the entity with this component.
|
||||
/// Once it's spawned, the entity will have a [`SceneInstance`] component.
|
||||
#[derive(Default, Bundle, Clone)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `SceneRoot` component instead. Inserting `SceneRoot` will also insert the other components required by scenes automatically."
|
||||
)]
|
||||
pub struct SceneBundle {
|
||||
/// Handle to the scene to spawn.
|
||||
pub scene: Handle<Scene>,
|
||||
pub scene: SceneRoot,
|
||||
/// Transform of the scene root entity.
|
||||
pub transform: Transform,
|
||||
/// Global transform of the scene root entity.
|
||||
|
@ -42,14 +47,18 @@ pub struct SceneBundle {
|
|||
pub view_visibility: ViewVisibility,
|
||||
}
|
||||
|
||||
/// A component bundle for a [`DynamicScene`] root.
|
||||
/// A component bundle for a [`DynamicScene`](crate::DynamicScene) root.
|
||||
///
|
||||
/// The dynamic scene from `scene` will be spawn as a child of the entity with this component.
|
||||
/// Once it's spawned, the entity will have a [`SceneInstance`] component.
|
||||
#[derive(Default, Bundle, Clone)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `DynamicSceneRoot` component instead. Inserting `DynamicSceneRoot` will also insert the other components required by scenes automatically."
|
||||
)]
|
||||
pub struct DynamicSceneBundle {
|
||||
/// Handle to the scene to spawn.
|
||||
pub scene: Handle<DynamicScene>,
|
||||
pub scene: DynamicSceneRoot,
|
||||
/// Transform of the scene root entity.
|
||||
pub transform: Transform,
|
||||
/// Global transform of the scene root entity.
|
||||
|
@ -66,21 +75,21 @@ pub struct DynamicSceneBundle {
|
|||
pub view_visibility: ViewVisibility,
|
||||
}
|
||||
|
||||
/// System that will spawn scenes from [`SceneBundle`].
|
||||
/// System that will spawn scenes from the [`SceneRoot`] and [`DynamicSceneRoot`] components.
|
||||
pub fn scene_spawner(
|
||||
mut commands: Commands,
|
||||
mut scene_to_spawn: Query<
|
||||
(Entity, &Handle<Scene>, Option<&mut SceneInstance>),
|
||||
(Changed<Handle<Scene>>, Without<Handle<DynamicScene>>),
|
||||
(Entity, &SceneRoot, Option<&mut SceneInstance>),
|
||||
(Changed<SceneRoot>, Without<DynamicSceneRoot>),
|
||||
>,
|
||||
mut dynamic_scene_to_spawn: Query<
|
||||
(Entity, &Handle<DynamicScene>, Option<&mut SceneInstance>),
|
||||
(Changed<Handle<DynamicScene>>, Without<Handle<Scene>>),
|
||||
(Entity, &DynamicSceneRoot, Option<&mut SceneInstance>),
|
||||
(Changed<DynamicSceneRoot>, Without<SceneRoot>),
|
||||
>,
|
||||
mut scene_spawner: ResMut<SceneSpawner>,
|
||||
) {
|
||||
for (entity, scene, instance) in &mut scene_to_spawn {
|
||||
let new_instance = scene_spawner.spawn_as_child(scene.clone(), entity);
|
||||
let new_instance = scene_spawner.spawn_as_child(scene.0.clone(), entity);
|
||||
if let Some(mut old_instance) = instance {
|
||||
scene_spawner.despawn_instance(**old_instance);
|
||||
*old_instance = SceneInstance(new_instance);
|
||||
|
@ -89,7 +98,7 @@ pub fn scene_spawner(
|
|||
}
|
||||
}
|
||||
for (entity, dynamic_scene, instance) in &mut dynamic_scene_to_spawn {
|
||||
let new_instance = scene_spawner.spawn_dynamic_as_child(dynamic_scene.clone(), entity);
|
||||
let new_instance = scene_spawner.spawn_dynamic_as_child(dynamic_scene.0.clone(), entity);
|
||||
if let Some(mut old_instance) = instance {
|
||||
scene_spawner.despawn_instance(**old_instance);
|
||||
*old_instance = SceneInstance(new_instance);
|
||||
|
@ -101,7 +110,7 @@ pub fn scene_spawner(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{DynamicScene, DynamicSceneBundle, ScenePlugin, SceneSpawner};
|
||||
use crate::{DynamicScene, DynamicSceneRoot, ScenePlugin, SceneSpawner};
|
||||
use bevy_app::{App, ScheduleRunnerPlugin};
|
||||
use bevy_asset::{AssetPlugin, Assets};
|
||||
use bevy_ecs::{
|
||||
|
@ -111,7 +120,6 @@ mod tests {
|
|||
};
|
||||
use bevy_hierarchy::{Children, HierarchyPlugin};
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_utils::default;
|
||||
|
||||
#[derive(Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
|
@ -143,13 +151,10 @@ mod tests {
|
|||
.resource_mut::<Assets<DynamicScene>>()
|
||||
.add(scene);
|
||||
|
||||
// spawn the scene as a child of `entity` using the `DynamicSceneBundle`
|
||||
// spawn the scene as a child of `entity` using `DynamicSceneRoot`
|
||||
let entity = app
|
||||
.world_mut()
|
||||
.spawn(DynamicSceneBundle {
|
||||
scene: scene_handle.clone(),
|
||||
..default()
|
||||
})
|
||||
.spawn(DynamicSceneRoot(scene_handle.clone()))
|
||||
.id();
|
||||
|
||||
// run the app's schedule once, so that the scene gets spawned
|
||||
|
|
36
crates/bevy_scene/src/components.rs
Normal file
36
crates/bevy_scene/src/components.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use bevy_asset::Handle;
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::component::Component;
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_transform::components::Transform;
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
use bevy_render::view::visibility::Visibility;
|
||||
|
||||
use crate::{DynamicScene, Scene};
|
||||
|
||||
/// Adding this component will spawn the scene as a child of that entity.
|
||||
/// Once it's spawned, the entity will have a [`SceneInstance`](crate::SceneInstance) component.
|
||||
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[require(Transform)]
|
||||
#[cfg_attr(feature = "bevy_render", require(Visibility))]
|
||||
pub struct SceneRoot(pub Handle<Scene>);
|
||||
|
||||
impl From<Handle<Scene>> for SceneRoot {
|
||||
fn from(handle: Handle<Scene>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
/// Adding this component will spawn the scene as a child of that entity.
|
||||
/// Once it's spawned, the entity will have a [`SceneInstance`](crate::SceneInstance) component.
|
||||
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[require(Transform)]
|
||||
#[cfg_attr(feature = "bevy_render", require(Visibility))]
|
||||
pub struct DynamicSceneRoot(pub Handle<DynamicScene>);
|
||||
|
||||
impl From<Handle<DynamicScene>> for DynamicSceneRoot {
|
||||
fn from(handle: Handle<DynamicScene>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
|
@ -18,10 +18,7 @@ use serde::Serialize;
|
|||
/// Each dynamic entity in the collection contains its own run-time defined set of components.
|
||||
/// To spawn a dynamic scene, you can use either:
|
||||
/// * [`SceneSpawner::spawn_dynamic`](crate::SceneSpawner::spawn_dynamic)
|
||||
/// * adding the [`DynamicSceneBundle`](crate::DynamicSceneBundle) to an entity
|
||||
/// * adding the [`Handle<DynamicScene>`](bevy_asset::Handle) to an entity (the scene will only be
|
||||
/// visible if the entity already has [`Transform`](bevy_transform::components::Transform) and
|
||||
/// [`GlobalTransform`](bevy_transform::components::GlobalTransform) components)
|
||||
/// * adding the [`DynamicSceneRoot`](crate::components::DynamicSceneRoot) component to an entity.
|
||||
/// * using the [`DynamicSceneBuilder`] to construct a `DynamicScene` from `World`.
|
||||
#[derive(Asset, TypePath, Default)]
|
||||
pub struct DynamicScene {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
extern crate alloc;
|
||||
|
||||
mod bundle;
|
||||
mod components;
|
||||
mod dynamic_scene;
|
||||
mod dynamic_scene_builder;
|
||||
mod scene;
|
||||
|
@ -29,6 +30,7 @@ pub use bevy_asset::ron;
|
|||
|
||||
use bevy_ecs::schedule::IntoSystemConfigs;
|
||||
pub use bundle::*;
|
||||
pub use components::*;
|
||||
pub use dynamic_scene::*;
|
||||
pub use dynamic_scene_builder::*;
|
||||
pub use scene::*;
|
||||
|
@ -39,16 +41,17 @@ pub use scene_spawner::*;
|
|||
/// The scene prelude.
|
||||
///
|
||||
/// This includes the most common types in this crate, re-exported for your convenience.
|
||||
#[expect(deprecated)]
|
||||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
DynamicScene, DynamicSceneBuilder, DynamicSceneBundle, Scene, SceneBundle, SceneFilter,
|
||||
SceneSpawner,
|
||||
DynamicScene, DynamicSceneBuilder, DynamicSceneBundle, DynamicSceneRoot, Scene,
|
||||
SceneBundle, SceneFilter, SceneRoot, SceneSpawner,
|
||||
};
|
||||
}
|
||||
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_asset::{AssetApp, Handle};
|
||||
use bevy_asset::AssetApp;
|
||||
|
||||
/// Plugin that provides scene functionality to an [`App`].
|
||||
#[derive(Default)]
|
||||
|
@ -61,13 +64,15 @@ impl Plugin for ScenePlugin {
|
|||
.init_asset::<Scene>()
|
||||
.init_asset_loader::<SceneLoader>()
|
||||
.init_resource::<SceneSpawner>()
|
||||
.register_type::<SceneRoot>()
|
||||
.register_type::<DynamicSceneRoot>()
|
||||
.add_systems(SpawnScene, (scene_spawner, scene_spawner_system).chain());
|
||||
|
||||
// Register component hooks for DynamicScene
|
||||
// Register component hooks for DynamicSceneRoot
|
||||
app.world_mut()
|
||||
.register_component_hooks::<Handle<DynamicScene>>()
|
||||
.register_component_hooks::<DynamicSceneRoot>()
|
||||
.on_remove(|mut world, entity, _| {
|
||||
let Some(handle) = world.get::<Handle<DynamicScene>>(entity) else {
|
||||
let Some(handle) = world.get::<DynamicSceneRoot>(entity) else {
|
||||
return;
|
||||
};
|
||||
let id = handle.id();
|
||||
|
@ -82,9 +87,9 @@ impl Plugin for ScenePlugin {
|
|||
}
|
||||
});
|
||||
|
||||
// Register component hooks for Scene
|
||||
// Register component hooks for SceneRoot
|
||||
app.world_mut()
|
||||
.register_component_hooks::<Handle<Scene>>()
|
||||
.register_component_hooks::<SceneRoot>()
|
||||
.on_remove(|mut world, entity, _| {
|
||||
if let Some(&SceneInstance(scene_instance)) = world.get::<SceneInstance>(entity) {
|
||||
let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
|
||||
|
|
|
@ -9,10 +9,7 @@ use bevy_reflect::{PartialReflect, TypePath};
|
|||
|
||||
/// To spawn a scene, you can use either:
|
||||
/// * [`SceneSpawner::spawn`](crate::SceneSpawner::spawn)
|
||||
/// * adding the [`SceneBundle`](crate::SceneBundle) to an entity
|
||||
/// * adding the [`Handle<Scene>`](bevy_asset::Handle) to an entity (the scene will only be
|
||||
/// visible if the entity already has [`Transform`](bevy_transform::components::Transform) and
|
||||
/// [`GlobalTransform`](bevy_transform::components::GlobalTransform) components)
|
||||
/// * adding the [`SceneRoot`](crate::components::SceneRoot) component to an entity.
|
||||
#[derive(Asset, TypePath, Debug)]
|
||||
pub struct Scene {
|
||||
/// The world of the scene, containing its entities and resources.
|
||||
|
|
|
@ -482,7 +482,7 @@ mod tests {
|
|||
};
|
||||
use bevy_reflect::Reflect;
|
||||
|
||||
use crate::{DynamicSceneBuilder, ScenePlugin};
|
||||
use crate::{DynamicSceneBuilder, DynamicSceneRoot, ScenePlugin};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -725,7 +725,8 @@ mod tests {
|
|||
|
||||
// Spawn scene.
|
||||
for _ in 0..count {
|
||||
app.world_mut().spawn((ComponentA, scene.clone()));
|
||||
app.world_mut()
|
||||
.spawn((ComponentA, DynamicSceneRoot(scene.clone())));
|
||||
}
|
||||
|
||||
app.update();
|
||||
|
|
|
@ -72,11 +72,10 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res
|
|||
|
||||
spawn_directional_light(&mut commands);
|
||||
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load("models/AnisotropyBarnLamp/AnisotropyBarnLamp.gltf#Scene0"),
|
||||
transform: Transform::from_xyz(0.0, 0.07, -0.13),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
SceneRoot(asset_server.load("models/AnisotropyBarnLamp/AnisotropyBarnLamp.gltf#Scene0")),
|
||||
Transform::from_xyz(0.0, 0.07, -0.13),
|
||||
));
|
||||
|
||||
spawn_text(&mut commands, &app_status);
|
||||
}
|
||||
|
|
|
@ -272,11 +272,9 @@ fn setup(
|
|||
}
|
||||
|
||||
// Flight Helmet
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"),
|
||||
)));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -69,11 +69,9 @@ fn setup_terrain_scene(
|
|||
));
|
||||
|
||||
// Terrain
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/terrain/Mountains.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/terrain/Mountains.gltf"),
|
||||
)));
|
||||
|
||||
// Sky
|
||||
commands.spawn((
|
||||
|
|
|
@ -145,14 +145,13 @@ fn spawn_coated_glass_bubble_sphere(
|
|||
/// This object is in glTF format, using the `KHR_materials_clearcoat`
|
||||
/// extension.
|
||||
fn spawn_golf_ball(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/GolfBall/GolfBall.glb")),
|
||||
transform: Transform::from_xyz(1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
..default()
|
||||
})
|
||||
.insert(ExampleSphere);
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/GolfBall/GolfBall.glb")),
|
||||
),
|
||||
Transform::from_xyz(1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
ExampleSphere,
|
||||
));
|
||||
}
|
||||
|
||||
/// Spawns an object with only a clearcoat normal map (a scratch pattern) and no
|
||||
|
|
|
@ -381,21 +381,18 @@ fn add_camera(commands: &mut Commands, asset_server: &AssetServer, color_grading
|
|||
|
||||
fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
// Spawn the main scene.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
)));
|
||||
|
||||
// Spawn the flight helmet.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
||||
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
),
|
||||
Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
));
|
||||
|
||||
// Spawn the light.
|
||||
commands.spawn((
|
||||
|
|
|
@ -85,15 +85,11 @@ fn setup(
|
|||
let helmet_scene = asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
|
||||
|
||||
commands.spawn(SceneBundle {
|
||||
scene: helmet_scene.clone(),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneBundle {
|
||||
scene: helmet_scene,
|
||||
transform: Transform::from_xyz(-4.0, 0.0, -3.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(helmet_scene.clone()));
|
||||
commands.spawn((
|
||||
SceneRoot(helmet_scene),
|
||||
Transform::from_xyz(-4.0, 0.0, -3.0),
|
||||
));
|
||||
|
||||
let mut forward_mat: StandardMaterial = Color::srgb(0.1, 0.2, 0.1).into();
|
||||
forward_mat.opaque_render_method = OpaqueRendererMethod::Forward;
|
||||
|
|
|
@ -88,13 +88,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: R
|
|||
}
|
||||
|
||||
// Spawn the scene.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
GltfAssetLabel::Scene(0)
|
||||
.from_asset("models/DepthOfFieldExample/DepthOfFieldExample.glb"),
|
||||
),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/DepthOfFieldExample/DepthOfFieldExample.glb"),
|
||||
)));
|
||||
|
||||
// Spawn the help text.
|
||||
commands.spawn(
|
||||
|
|
|
@ -227,10 +227,7 @@ fn setup(mut commands: Commands, assets: Res<ExampleAssets>, app_status: Res<App
|
|||
}
|
||||
|
||||
fn spawn_main_scene(commands: &mut Commands, assets: &ExampleAssets) {
|
||||
commands.spawn(SceneBundle {
|
||||
scene: assets.main_scene.clone(),
|
||||
..SceneBundle::default()
|
||||
});
|
||||
commands.spawn(SceneRoot(assets.main_scene.clone()));
|
||||
}
|
||||
|
||||
fn spawn_camera(commands: &mut Commands, assets: &ExampleAssets) {
|
||||
|
@ -290,14 +287,12 @@ fn spawn_voxel_cube_parent(commands: &mut Commands) {
|
|||
}
|
||||
|
||||
fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: assets.fox.clone(),
|
||||
visibility: Visibility::Hidden,
|
||||
transform: Transform::from_scale(Vec3::splat(FOX_SCALE)),
|
||||
..default()
|
||||
})
|
||||
.insert(MainObject);
|
||||
commands.spawn((
|
||||
SceneRoot(assets.fox.clone()),
|
||||
Visibility::Hidden,
|
||||
Transform::from_scale(Vec3::splat(FOX_SCALE)),
|
||||
MainObject,
|
||||
));
|
||||
}
|
||||
|
||||
fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
||||
|
@ -386,11 +381,8 @@ fn rotate_camera(
|
|||
fn change_main_object(
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
mut app_status: ResMut<AppStatus>,
|
||||
mut sphere_query: Query<
|
||||
&mut Visibility,
|
||||
(With<MainObject>, With<Mesh3d>, Without<Handle<Scene>>),
|
||||
>,
|
||||
mut fox_query: Query<&mut Visibility, (With<MainObject>, With<Handle<Scene>>)>,
|
||||
mut sphere_query: Query<&mut Visibility, (With<MainObject>, With<Mesh3d>, Without<SceneRoot>)>,
|
||||
mut fox_query: Query<&mut Visibility, (With<MainObject>, With<SceneRoot>)>,
|
||||
) {
|
||||
if !keyboard.just_pressed(KeyCode::Tab) {
|
||||
return;
|
||||
|
|
|
@ -12,11 +12,9 @@ fn main() {
|
|||
}
|
||||
|
||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/CornellBox/CornellBox.glb")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/CornellBox/CornellBox.glb"),
|
||||
)));
|
||||
|
||||
commands.spawn(Camera3dBundle {
|
||||
transform: Transform::from_xyz(-278.0, 273.0, 800.0),
|
||||
|
|
|
@ -46,11 +46,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
}
|
||||
.build(),
|
||||
));
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"),
|
||||
)));
|
||||
}
|
||||
|
||||
fn animate_light_direction(
|
||||
|
|
|
@ -28,11 +28,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
});
|
||||
|
||||
// a barebones scene containing one of each gltf_extra type
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/extras/gltf_extras.glb")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/extras/gltf_extras.glb"),
|
||||
)));
|
||||
|
||||
// a place to display the extras on screen
|
||||
commands.spawn((
|
||||
|
|
|
@ -205,10 +205,9 @@ fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
|
|||
|
||||
/// Loads and spawns the glTF palm tree scene.
|
||||
fn spawn_gltf_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load("models/PalmTree/PalmTree.gltf#Scene0"),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(
|
||||
asset_server.load("models/PalmTree/PalmTree.gltf#Scene0"),
|
||||
));
|
||||
}
|
||||
|
||||
/// Spawns all the buttons at the bottom of the screen.
|
||||
|
|
|
@ -93,21 +93,18 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
|||
/// variety of colors.
|
||||
fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
// Spawn the main scene.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
)));
|
||||
|
||||
// Spawn the flight helmet.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
||||
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
),
|
||||
Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
));
|
||||
|
||||
// Spawn the light.
|
||||
commands.spawn((
|
||||
|
|
|
@ -83,13 +83,13 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
}
|
||||
.build(),
|
||||
));
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb")),
|
||||
transform: Transform {
|
||||
commands.spawn((
|
||||
SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
|
||||
)),
|
||||
Transform {
|
||||
rotation: Quat::from_rotation_y(-90.0 / 180.0 * PI),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
});
|
||||
));
|
||||
}
|
||||
|
|
|
@ -96,10 +96,9 @@ fn setup(
|
|||
|
||||
// Spawns the cubes, light, and camera.
|
||||
fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/cubes/Cubes.glb")),
|
||||
..SceneBundle::default()
|
||||
});
|
||||
commands.spawn(SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/cubes/Cubes.glb")),
|
||||
));
|
||||
}
|
||||
|
||||
// Spawns the camera.
|
||||
|
|
|
@ -27,10 +27,9 @@ fn setup(
|
|||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -163,15 +163,15 @@ fn spawn_cube(
|
|||
|
||||
// Spawns the flight helmet.
|
||||
fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
transform: Transform::from_scale(Vec3::splat(2.5)),
|
||||
..default()
|
||||
})
|
||||
.insert(FlightHelmetModel)
|
||||
.insert(Visibility::Hidden);
|
||||
),
|
||||
Transform::from_scale(Vec3::splat(2.5)),
|
||||
FlightHelmetModel,
|
||||
Visibility::Hidden,
|
||||
));
|
||||
}
|
||||
|
||||
// Spawns the water plane.
|
||||
|
|
|
@ -95,24 +95,20 @@ fn setup(
|
|||
|
||||
fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// Main scene
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
),
|
||||
..default()
|
||||
})
|
||||
.insert(SceneNumber(1));
|
||||
commands.spawn((
|
||||
SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||
)),
|
||||
SceneNumber(1),
|
||||
));
|
||||
|
||||
// Flight Helmet
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
scene: asset_server
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
||||
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
..default()
|
||||
},
|
||||
),
|
||||
Transform::from_xyz(0.5, 0.0, -0.5).with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||
SceneNumber(1),
|
||||
));
|
||||
|
||||
|
|
|
@ -38,20 +38,20 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
));
|
||||
|
||||
// Spawn the scene as a child of this entity at the given transform
|
||||
commands.spawn(SceneBundle {
|
||||
transform: Transform::from_xyz(-1.0, 0.0, 0.0),
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Transform::from_xyz(-1.0, 0.0, 0.0),
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
),
|
||||
));
|
||||
|
||||
// Spawn a second scene, and add a tag component to be able to target it later
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
scene: asset_server
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
..default()
|
||||
},
|
||||
),
|
||||
MovedScene,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -101,23 +101,23 @@ fn setup(
|
|||
|
||||
// Spawn the two HLODs.
|
||||
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||
..default()
|
||||
})
|
||||
.insert(MainModel::HighPoly);
|
||||
),
|
||||
MainModel::HighPoly,
|
||||
));
|
||||
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server.load(
|
||||
GltfAssetLabel::Scene(0)
|
||||
.from_asset("models/FlightHelmetLowPoly/FlightHelmetLowPoly.gltf"),
|
||||
),
|
||||
..default()
|
||||
})
|
||||
.insert(MainModel::LowPoly);
|
||||
),
|
||||
MainModel::LowPoly,
|
||||
));
|
||||
|
||||
// Spawn a light.
|
||||
commands.spawn((
|
||||
|
|
|
@ -57,13 +57,9 @@ fn main() {
|
|||
/// Initializes the scene.
|
||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: Res<AppSettings>) {
|
||||
// Spawn the glTF scene.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(
|
||||
GltfAssetLabel::Scene(0)
|
||||
.from_asset("models/VolumetricFogExample/VolumetricFogExample.glb"),
|
||||
),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/VolumetricFogExample/VolumetricFogExample.glb"),
|
||||
)));
|
||||
|
||||
// Spawn the camera.
|
||||
commands
|
||||
|
|
|
@ -80,10 +80,9 @@ fn setup(
|
|||
));
|
||||
|
||||
// Fox
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset(FOX_PATH)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset(FOX_PATH)),
|
||||
));
|
||||
|
||||
println!("Animation controls:");
|
||||
println!(" - spacebar: play / pause");
|
||||
|
|
|
@ -232,11 +232,12 @@ fn setup_scene(
|
|||
Transform::from_xyz(-4.0, 8.0, 13.0),
|
||||
));
|
||||
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
transform: Transform::from_scale(Vec3::splat(0.07)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
),
|
||||
Transform::from_scale(Vec3::splat(0.07)),
|
||||
));
|
||||
|
||||
// Ground
|
||||
|
||||
|
|
|
@ -118,11 +118,12 @@ fn setup_scene(
|
|||
));
|
||||
|
||||
// Spawn the fox.
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
transform: Transform::from_scale(Vec3::splat(0.07)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
),
|
||||
Transform::from_scale(Vec3::splat(0.07)),
|
||||
));
|
||||
|
||||
// Spawn the ground.
|
||||
commands.spawn((
|
||||
|
|
|
@ -26,11 +26,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
});
|
||||
|
||||
// Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/SimpleSkin/SimpleSkin.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/SimpleSkin/SimpleSkin.gltf"),
|
||||
)));
|
||||
}
|
||||
|
||||
/// The scene hierarchy currently looks somewhat like this:
|
||||
|
|
|
@ -46,11 +46,9 @@ fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
|
|||
.from_asset("models/animated/MorphStressTest.gltf"),
|
||||
),
|
||||
});
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/animated/MorphStressTest.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(asset_server.load(
|
||||
GltfAssetLabel::Scene(0).from_asset("models/animated/MorphStressTest.gltf"),
|
||||
)));
|
||||
commands.spawn((
|
||||
DirectionalLight::default(),
|
||||
Transform::from_rotation(Quat::from_rotation_z(PI / 2.0)),
|
||||
|
|
|
@ -23,10 +23,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
// You should see the changes immediately show up in your app.
|
||||
|
||||
// mesh
|
||||
commands.spawn(SceneBundle {
|
||||
scene: scene_handle,
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(scene_handle));
|
||||
// light
|
||||
commands.spawn((
|
||||
DirectionalLight::default(),
|
||||
|
|
|
@ -261,11 +261,7 @@ fn wait_on_load(
|
|||
// All gltfs must exist because this is guarded by the `AssetBarrier`.
|
||||
let gltf = gltfs.get(&foxes.0[index]).unwrap();
|
||||
let scene = gltf.scenes.first().unwrap().clone();
|
||||
commands.spawn(SceneBundle {
|
||||
scene,
|
||||
transform: Transform::from_translation(position),
|
||||
..Default::default()
|
||||
});
|
||||
commands.spawn((SceneRoot(scene), Transform::from_translation(position)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,14 +78,12 @@ fn setup(
|
|||
|
||||
commands.spawn((
|
||||
Name::new("Fox"),
|
||||
SceneBundle {
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
// Note: the scale adjustment is purely an accident of our fox model, which renders
|
||||
// HUGE unless mitigated!
|
||||
transform: Transform::from_translation(Vec3::splat(0.0)).with_scale(Vec3::splat(0.025)),
|
||||
..default()
|
||||
},
|
||||
SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
),
|
||||
// Note: the scale adjustment is purely an accident of our fox model, which renders
|
||||
// HUGE unless mitigated!
|
||||
Transform::from_translation(Vec3::splat(0.0)).with_scale(Vec3::splat(0.025)),
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
|
|
|
@ -139,11 +139,10 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
|||
(0..BOARD_SIZE_I)
|
||||
.map(|i| {
|
||||
let height = rng.gen_range(-0.1..0.1);
|
||||
commands.spawn(SceneBundle {
|
||||
transform: Transform::from_xyz(i as f32, height - 0.2, j as f32),
|
||||
scene: cell_scene.clone(),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Transform::from_xyz(i as f32, height - 0.2, j as f32),
|
||||
SceneRoot(cell_scene.clone()),
|
||||
));
|
||||
Cell { height }
|
||||
})
|
||||
.collect()
|
||||
|
@ -153,8 +152,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
|||
// spawn the game character
|
||||
game.player.entity = Some(
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
transform: Transform {
|
||||
.spawn((
|
||||
Transform {
|
||||
translation: Vec3::new(
|
||||
game.player.i as f32,
|
||||
game.board[game.player.j][game.player.i].height,
|
||||
|
@ -163,10 +162,11 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
|||
rotation: Quat::from_rotation_y(-PI / 2.),
|
||||
..default()
|
||||
},
|
||||
scene: asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/AlienCake/alien.glb")),
|
||||
..default()
|
||||
})
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/AlienCake/alien.glb")),
|
||||
),
|
||||
))
|
||||
.id(),
|
||||
);
|
||||
|
||||
|
@ -345,15 +345,14 @@ fn spawn_bonus(
|
|||
}
|
||||
game.bonus.entity = Some(
|
||||
commands
|
||||
.spawn(SceneBundle {
|
||||
transform: Transform::from_xyz(
|
||||
.spawn((
|
||||
Transform::from_xyz(
|
||||
game.bonus.i as f32,
|
||||
game.board[game.bonus.j][game.bonus.i].height + 0.2,
|
||||
game.bonus.j as f32,
|
||||
),
|
||||
scene: game.bonus.handle.clone(),
|
||||
..default()
|
||||
})
|
||||
SceneRoot(game.bonus.handle.clone()),
|
||||
))
|
||||
.with_child((
|
||||
PointLight {
|
||||
color: Color::srgb(1.0, 1.0, 0.0),
|
||||
|
|
|
@ -154,11 +154,8 @@ fn load_level_1(
|
|||
loading_data.loading_assets.push(fox.clone().into());
|
||||
// Spawn the fox.
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
scene: fox.clone(),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
SceneRoot(fox.clone()),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
LevelComponents,
|
||||
));
|
||||
|
||||
|
@ -194,13 +191,7 @@ fn load_level_2(
|
|||
loading_data
|
||||
.loading_assets
|
||||
.push(helmet_scene.clone().into());
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
scene: helmet_scene.clone(),
|
||||
..default()
|
||||
},
|
||||
LevelComponents,
|
||||
));
|
||||
commands.spawn((SceneRoot(helmet_scene.clone()), LevelComponents));
|
||||
|
||||
// Spawn the light.
|
||||
commands.spawn((
|
||||
|
|
|
@ -65,13 +65,10 @@ const SCENE_FILE_PATH: &str = "scenes/load_scene_example.scn.ron";
|
|||
const NEW_SCENE_FILE_PATH: &str = "scenes/load_scene_example-new.scn.ron";
|
||||
|
||||
fn load_scene_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// "Spawning" a scene bundle creates a new entity and spawns new instances
|
||||
// Spawning a DynamicSceneRoot creates a new entity and spawns new instances
|
||||
// of the given scene's entities as children of that entity.
|
||||
commands.spawn(DynamicSceneBundle {
|
||||
// Scenes are loaded just like any other asset.
|
||||
scene: asset_server.load(SCENE_FILE_PATH),
|
||||
..default()
|
||||
});
|
||||
// Scenes can be loaded just like any other asset.
|
||||
commands.spawn(DynamicSceneRoot(asset_server.load(SCENE_FILE_PATH)));
|
||||
}
|
||||
|
||||
// This system logs all ComponentA components in our world. Try making a change to a ComponentA in
|
||||
|
|
|
@ -172,13 +172,12 @@ fn setup(
|
|||
let (x, z) = (radius * c, radius * s);
|
||||
|
||||
commands.entity(ring_parent).with_children(|builder| {
|
||||
builder.spawn(SceneBundle {
|
||||
scene: fox_handle.clone(),
|
||||
transform: Transform::from_xyz(x, 0.0, z)
|
||||
builder.spawn((
|
||||
SceneRoot(fox_handle.clone()),
|
||||
Transform::from_xyz(x, 0.0, z)
|
||||
.with_scale(Vec3::splat(0.01))
|
||||
.with_rotation(base_rotation * Quat::from_rotation_y(-fox_angle)),
|
||||
..default()
|
||||
});
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -81,11 +81,10 @@ fn setup(
|
|||
|
||||
// Finally, our ship that is going to rotate
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
scene: asset_server
|
||||
SceneRoot(
|
||||
asset_server
|
||||
.load(GltfAssetLabel::Scene(0).from_asset("models/ship/craft_speederD.gltf")),
|
||||
..default()
|
||||
},
|
||||
),
|
||||
Ship {
|
||||
target_transform: random_axes_target_alignment(&RandomAxes(first, second)),
|
||||
..default()
|
||||
|
|
|
@ -12,10 +12,9 @@ fn main() {
|
|||
|
||||
fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// add entities to the world
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(SceneRoot(
|
||||
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
|
||||
));
|
||||
// light
|
||||
commands.spawn((
|
||||
DirectionalLight::default(),
|
||||
|
|
Loading…
Reference in a new issue