Spawn now takes a Bundle (#6054)

# Objective

Now that we can consolidate Bundles and Components under a single insert (thanks to #2975 and #6039), almost 100% of world spawns now look like `world.spawn().insert((Some, Tuple, Here))`. Spawning an entity without any components is an extremely uncommon pattern, so it makes sense to give spawn the "first class" ergonomic api. This consolidated api should be made consistent across all spawn apis (such as World and Commands).

## Solution

All `spawn` apis (`World::spawn`, `Commands:;spawn`, `ChildBuilder::spawn`, and `WorldChildBuilder::spawn`) now accept a bundle as input:

```rust
// before:
commands
  .spawn()
  .insert((A, B, C));
world
  .spawn()
  .insert((A, B, C);

// after
commands.spawn((A, B, C));
world.spawn((A, B, C));
```

All existing instances of `spawn_bundle` have been deprecated in favor of the new `spawn` api. A new `spawn_empty` has been added, replacing the old `spawn` api.  

By allowing `world.spawn(some_bundle)` to replace `world.spawn().insert(some_bundle)`, this opened the door to removing the initial entity allocation in the "empty" archetype / table done in `spawn()` (and subsequent move to the actual archetype in `.insert(some_bundle)`).

This improves spawn performance by over 10%:
![image](https://user-images.githubusercontent.com/2694663/191627587-4ab2f949-4ccd-4231-80eb-80dd4d9ad6b9.png)

To take this measurement, I added a new `world_spawn` benchmark.

Unfortunately, optimizing `Commands::spawn` is slightly less trivial, as Commands expose the Entity id of spawned entities prior to actually spawning. Doing the optimization would (naively) require assurances that the `spawn(some_bundle)` command is applied before all other commands involving the entity (which would not necessarily be true, if memory serves). Optimizing `Commands::spawn` this way does feel possible, but it will require careful thought (and maybe some additional checks), which deserves its own PR. For now, it has the same performance characteristics of the current `Commands::spawn_bundle` on main.

**Note that 99% of this PR is simple renames and refactors. The only code that needs careful scrutiny is the new `World::spawn()` impl, which is relatively straightforward, but it has some new unsafe code (which re-uses battle tested BundlerSpawner code path).** 

---

## Changelog

- All `spawn` apis (`World::spawn`, `Commands:;spawn`, `ChildBuilder::spawn`, and `WorldChildBuilder::spawn`) now accept a bundle as input
- All instances of `spawn_bundle` have been deprecated in favor of the new `spawn` api
- World and Commands now have `spawn_empty()`, which is equivalent to the old `spawn()` behavior.  

## Migration Guide

```rust
// Old (0.8):
commands
  .spawn()
  .insert_bundle((A, B, C));
// New (0.9)
commands.spawn((A, B, C));

// Old (0.8):
commands.spawn_bundle((A, B, C));
// New (0.9)
commands.spawn((A, B, C));

// Old (0.8):
let entity = commands.spawn().id();
// New (0.9)
let entity = commands.spawn_empty().id();

// Old (0.8)
let entity = world.spawn().id();
// New (0.9)
let entity = world.spawn_empty();
```
This commit is contained in:
Carter Anderson 2022-09-23 19:55:54 +00:00
parent fb74ca3d46
commit 01aedc8431
164 changed files with 1504 additions and 1382 deletions

View file

@ -26,8 +26,7 @@ impl Benchmark {
for _ in 0..10_000 {
entities.push(
world
.spawn()
.insert((
.spawn((
A(Mat4::from_scale(Vec3::ONE)),
B(Mat4::from_scale(Vec3::ONE)),
C(Mat4::from_scale(Vec3::ONE)),

View file

@ -25,8 +25,7 @@ impl Benchmark {
for _ in 0..10_000 {
entities.push(
world
.spawn()
.insert((
.spawn((
A(Mat4::from_scale(Vec3::ONE)),
B(Mat4::from_scale(Vec3::ONE)),
C(Mat4::from_scale(Vec3::ONE)),

View file

@ -13,7 +13,7 @@ impl Benchmark {
let mut world = World::default();
let mut entities = Vec::with_capacity(10_000);
for _ in 0..10_000 {
entities.push(world.spawn().insert(A(0.0)).id());
entities.push(world.spawn(A(0.0)).id());
}
Self(world, entities)

View file

@ -12,7 +12,7 @@ impl Benchmark {
let mut world = World::default();
let mut entities = Vec::with_capacity(10_000);
for _ in 0..10_000 {
entities.push(world.spawn().insert(A(0.0)).id());
entities.push(world.spawn(A(0.0)).id());
}
Self(world, entities)

View file

@ -22,7 +22,7 @@ fn setup(system_count: usize) -> (World, SystemStage) {
/// create `count` entities with distinct archetypes
fn add_archetypes(world: &mut World, count: u16) {
for i in 0..count {
let mut e = world.spawn();
let mut e = world.spawn_empty();
if i & 1 << 0 != 0 {
e.insert(A::<0>(1.0));
}

View file

@ -23,7 +23,7 @@ impl Benchmark {
pub fn run(&mut self) {
let mut world = World::new();
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert(($variants(0.0), Data(1.0)));
$world.spawn(($variants(0.0), Data(1.0)));
}
)*
};

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert(($variants(0.0), Data(1.0)));
$world.spawn(($variants(0.0), Data(1.0)));
}
)*
};

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..5 {
$world.spawn().insert($variants(0.0));
$world.spawn($variants(0.0));
}
)*
};
@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
pub fn new() -> Self {
let mut world = World::new();
for _ in 0..5 {
world.spawn().insert(Data(1.0));
world.spawn(Data(1.0));
}
create_entities!(world; C00, C01, C02, C03, C04, C05, C06, C07, C08, C09);

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert((
$world.spawn((
$variants(0.0),
Data::<0>(1.0),
Data::<1>(1.0),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..5 {
$world.spawn().insert($variants(0.0));
$world.spawn($variants(0.0));
}
)*
};
@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> {
pub fn new() -> Self {
let mut world = World::new();
for _ in 0..5 {
world.spawn().insert((
world.spawn((
Data::<0>(1.0),
Data::<1>(1.0),
Data::<2>(1.0),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..5 {
$world.spawn().insert($variants(0.0));
$world.spawn($variants(0.0));
}
)*
};
@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
let mut world = World::new();
for _ in 0..5 {
world.spawn().insert(Data(1.0));
world.spawn(Data(1.0));
}
create_entities!(world; C00, C01, C02, C03, C04, C05, C06, C07, C08, C09);

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert((
$world.spawn((
$variants(0.0),
Data::<0>(1.0),
Data::<1>(1.0),

View file

@ -6,7 +6,7 @@ macro_rules! create_entities {
#[derive(Component)]
struct $variants(f32);
for _ in 0..5 {
$world.spawn().insert($variants(0.0));
$world.spawn($variants(0.0));
}
)*
};
@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> {
let mut world = World::new();
for _ in 0..5 {
world.spawn().insert((
world.spawn((
Data::<0>(1.0),
Data::<1>(1.0),
Data::<2>(1.0),

View file

@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -21,7 +21,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -35,7 +35,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X),
Position::<0>(Vec3::X),

View file

@ -37,7 +37,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X),
Position::<0>(Vec3::X),

View file

@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -21,7 +21,7 @@ impl Benchmark {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),

View file

@ -35,7 +35,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X),
Position::<0>(Vec3::X),

View file

@ -37,7 +37,7 @@ impl<'w> Benchmark<'w> {
// TODO: batch this
for _ in 0..10_000 {
world.spawn().insert((
world.spawn((
Transform(Mat4::from_scale(Vec3::ONE)),
Rotation(Vec3::X),
Position::<0>(Vec3::X),

View file

@ -150,7 +150,7 @@ struct TestBool(pub bool);
pub fn run_criteria_yes_with_query(criterion: &mut Criterion) {
let mut world = World::new();
world.spawn().insert(TestBool(true));
world.spawn(TestBool(true));
let mut group = criterion.benchmark_group("run_criteria/yes_using_query");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(3));

View file

@ -43,7 +43,7 @@ pub fn spawn_commands(criterion: &mut Criterion) {
bencher.iter(|| {
let mut commands = Commands::new(&mut command_queue, &world);
for i in 0..entity_count {
let mut entity = commands.spawn();
let mut entity = commands.spawn_empty();
if black_box(i % 2 == 0) {
entity.insert(A);
@ -87,7 +87,7 @@ pub fn insert_commands(criterion: &mut Criterion) {
let mut command_queue = CommandQueue::default();
let mut entities = Vec::new();
for _ in 0..entity_count {
entities.push(world.spawn().id());
entities.push(world.spawn_empty().id());
}
bencher.iter(|| {
@ -106,7 +106,7 @@ pub fn insert_commands(criterion: &mut Criterion) {
let mut command_queue = CommandQueue::default();
let mut entities = Vec::new();
for _ in 0..entity_count {
entities.push(world.spawn().id());
entities.push(world.spawn_empty().id());
}
bencher.iter(|| {

View file

@ -1,9 +1,11 @@
use criterion::criterion_group;
mod commands;
mod spawn;
mod world_get;
use commands::*;
use spawn::*;
use world_get::*;
criterion_group!(
@ -21,6 +23,7 @@ criterion_group!(
world_query_get,
world_query_iter,
world_query_for_each,
world_spawn,
query_get_component_simple,
query_get_component,
query_get,

View file

@ -0,0 +1,27 @@
use bevy_ecs::prelude::*;
use criterion::Criterion;
use glam::*;
#[derive(Component)]
struct A(Mat4);
#[derive(Component)]
struct B(Vec4);
pub fn world_spawn(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("spawn_world");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
for entity_count in (0..5).map(|i| 10_u32.pow(i)) {
group.bench_function(format!("{}_entities", entity_count), |bencher| {
let mut world = World::default();
bencher.iter(|| {
for _ in 0..entity_count {
world.spawn((A(Mat4::default()), B(Vec4::default())));
}
});
});
}
group.finish();
}

View file

@ -268,7 +268,7 @@ pub fn query_get_component_simple(criterion: &mut Criterion) {
group.bench_function("unchecked", |bencher| {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
let entity = world.spawn(A(0.0)).id();
let mut query = world.query::<&mut A>();
bencher.iter(|| {
@ -281,7 +281,7 @@ pub fn query_get_component_simple(criterion: &mut Criterion) {
group.bench_function("system", |bencher| {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
let entity = world.spawn(A(0.0)).id();
fn query_system(In(entity): In<Entity>, mut query: Query<&mut A>) {
for _ in 0..100_000 {
let mut a = query.get_mut(entity).unwrap();

View file

@ -57,9 +57,8 @@ struct Velocity { x: f32, y: f32 }
let mut world = World::new();
let entity = world.spawn()
.insert(Position { x: 0.0, y: 0.0 })
.insert(Velocity { x: 1.0, y: 0.0 })
let entity = world
.spawn((Position { x: 0.0, y: 0.0 }, Velocity { x: 1.0, y: 0.0 }))
.id();
let entity_ref = world.entity(entity);
@ -141,9 +140,10 @@ fn main() {
let mut world = World::new();
// Spawn an entity with Position and Velocity components
world.spawn()
.insert(Position { x: 0.0, y: 0.0 })
.insert(Velocity { x: 1.0, y: 0.0 });
world.spawn((
Position { x: 0.0, y: 0.0 },
Velocity { x: 1.0, y: 0.0 },
));
// Create a new Schedule, which defines an execution strategy for Systems
let mut schedule = Schedule::default();
@ -276,10 +276,10 @@ struct PlayerBundle {
let mut world = World::new();
// Spawn a new entity and insert the default PlayerBundle
world.spawn().insert(PlayerBundle::default());
world.spawn(PlayerBundle::default());
// Bundles play well with Rust's struct update syntax
world.spawn().insert(PlayerBundle {
world.spawn(PlayerBundle {
position: Position { x: 1.0, y: 1.0 },
..Default::default()
});

View file

@ -65,7 +65,7 @@ enum SimulationSystem {
// If an entity gets spawned, we increase the counter in the EntityCounter resource
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
if rand::thread_rng().gen_bool(0.6) {
let entity_id = commands.spawn_bundle(Age::default()).id();
let entity_id = commands.spawn(Age::default()).id();
println!(" spawning {:?}", entity_id);
entity_counter.value += 1;
}

View file

@ -376,7 +376,7 @@ mod tests {
let mut world = World::new();
// component added: 1, changed: 1
world.spawn().insert(C);
world.spawn(C);
let mut change_detected_system = IntoSystem::into_system(change_detected);
let mut change_expired_system = IntoSystem::into_system(change_expired);
@ -409,7 +409,7 @@ mod tests {
*world.change_tick.get_mut() = 0;
// component added: 0, changed: 0
world.spawn().insert(C);
world.spawn(C);
// system last ran: u32::MAX
let mut change_detected_system = IntoSystem::into_system(change_detected);
@ -425,7 +425,7 @@ mod tests {
let mut world = World::new();
// component added: 1, changed: 1
world.spawn().insert(C);
world.spawn(C);
// a bunch of stuff happens, the component is now older than `MAX_CHANGE_AGE`
*world.change_tick.get_mut() += MAX_CHANGE_AGE + CHECK_TICK_THRESHOLD;

View file

@ -13,20 +13,20 @@
//!
//! |Operation|Command|Method|
//! |:---:|:---:|:---:|
//! |Spawn a new entity|[`Commands::spawn`]|[`World::spawn`]|
//! |Spawn an entity with components|[`Commands::spawn_bundle`]|---|
//! |Spawn an entity with components|[`Commands::spawn`]|---|
//! |Spawn an entity without components|[`Commands::spawn_empty`]|[`World::spawn_empty`]|
//! |Despawn an entity|[`EntityCommands::despawn`]|[`World::despawn`]|
//! |Insert a component, bundle, or tuple of components and bundles to an entity|[`EntityCommands::insert`]|[`EntityMut::insert`]|
//! |Remove a component, bundle, or tuple of components and bundles from an entity|[`EntityCommands::remove`]|[`EntityMut::remove`]|
//!
//! [`World`]: crate::world::World
//! [`Commands::spawn`]: crate::system::Commands::spawn
//! [`Commands::spawn_bundle`]: crate::system::Commands::spawn_bundle
//! [`Commands::spawn_empty`]: crate::system::Commands::spawn_empty
//! [`EntityCommands::despawn`]: crate::system::EntityCommands::despawn
//! [`EntityCommands::insert`]: crate::system::EntityCommands::insert
//! [`EntityCommands::remove`]: crate::system::EntityCommands::remove
//! [`World::spawn`]: crate::world::World::spawn
//! [`World::spawn_bundle`]: crate::world::World::spawn_bundle
//! [`World::spawn_empty`]: crate::world::World::spawn_empty
//! [`World::despawn`]: crate::world::World::despawn
//! [`EntityMut::insert`]: crate::world::EntityMut::insert
//! [`EntityMut::remove`]: crate::world::EntityMut::remove
@ -66,15 +66,16 @@ type IdCursor = isize;
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)]
/// # struct SomeComponent;
/// fn setup(mut commands: Commands) {
/// // Calling `spawn` returns `EntityCommands`.
/// let entity = commands.spawn().id();
/// let entity = commands.spawn(SomeComponent).id();
/// }
///
/// fn exclusive_system(world: &mut World) {
/// // Calling `spawn` returns `EntityMut`.
/// let entity = world.spawn().id();
/// let entity = world.spawn(SomeComponent).id();
/// }
/// #
/// # bevy_ecs::system::assert_is_system(setup);

View file

@ -109,13 +109,9 @@ mod tests {
fn random_access() {
let mut world = World::new();
let e = world
.spawn()
.insert((TableStored("abc"), SparseStored(123)))
.id();
let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
let f = world
.spawn()
.insert((TableStored("def"), SparseStored(456), A(1)))
.spawn((TableStored("def"), SparseStored(456), A(1)))
.id();
assert_eq!(world.get::<TableStored>(e).unwrap().0, "abc");
assert_eq!(world.get::<SparseStored>(e).unwrap().0, 123);
@ -158,15 +154,13 @@ mod tests {
);
let e1 = world
.spawn()
.insert(FooBundle {
.spawn(FooBundle {
x: TableStored("abc"),
y: SparseStored(123),
})
.id();
let e2 = world
.spawn()
.insert((TableStored("def"), SparseStored(456), A(1)))
.spawn((TableStored("def"), SparseStored(456), A(1)))
.id();
assert_eq!(world.get::<TableStored>(e1).unwrap().0, "abc");
assert_eq!(world.get::<SparseStored>(e1).unwrap().0, 123);
@ -216,8 +210,7 @@ mod tests {
);
let e3 = world
.spawn()
.insert(NestedBundle {
.spawn(NestedBundle {
a: A(1),
foo: FooBundle {
x: TableStored("ghi"),
@ -247,8 +240,8 @@ mod tests {
#[test]
fn despawn_table_storage() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world.spawn().insert((TableStored("def"), A(456))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456))).id();
assert_eq!(world.entities.len(), 2);
assert!(world.despawn(e));
assert_eq!(world.entities.len(), 1);
@ -262,14 +255,8 @@ mod tests {
fn despawn_mixed_storage() {
let mut world = World::new();
let e = world
.spawn()
.insert((TableStored("abc"), SparseStored(123)))
.id();
let f = world
.spawn()
.insert((TableStored("def"), SparseStored(456)))
.id();
let e = world.spawn((TableStored("abc"), SparseStored(123))).id();
let f = world.spawn((TableStored("def"), SparseStored(456))).id();
assert_eq!(world.entities.len(), 2);
assert!(world.despawn(e));
assert_eq!(world.entities.len(), 1);
@ -282,8 +269,8 @@ mod tests {
#[test]
fn query_all() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world.spawn().insert((TableStored("def"), A(456))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456))).id();
let ents = world
.query::<(Entity, &A, &TableStored)>()
@ -302,8 +289,8 @@ mod tests {
#[test]
fn query_all_for_each() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world.spawn().insert((TableStored("def"), A(456))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456))).id();
let mut results = Vec::new();
world
@ -321,11 +308,8 @@ mod tests {
#[test]
fn query_single_component() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world
.spawn()
.insert((TableStored("def"), A(456), B(1)))
.id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456), B(1))).id();
let ents = world
.query::<(Entity, &A)>()
.iter(&world)
@ -337,16 +321,13 @@ mod tests {
#[test]
fn stateful_query_handles_new_archetype() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let mut query = world.query::<(Entity, &A)>();
let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
assert_eq!(ents, &[(e, A(123))]);
let f = world
.spawn()
.insert((TableStored("def"), A(456), B(1)))
.id();
let f = world.spawn((TableStored("def"), A(456), B(1))).id();
let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::<Vec<_>>();
assert_eq!(ents, &[(e, A(123)), (f, A(456))]);
}
@ -354,11 +335,8 @@ mod tests {
#[test]
fn query_single_component_for_each() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world
.spawn()
.insert((TableStored("def"), A(456), B(1)))
.id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456), B(1))).id();
let mut results = Vec::new();
world
.query::<(Entity, &A)>()
@ -370,11 +348,11 @@ mod tests {
fn par_for_each_dense() {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::new();
let e1 = world.spawn().insert(A(1)).id();
let e2 = world.spawn().insert(A(2)).id();
let e3 = world.spawn().insert(A(3)).id();
let e4 = world.spawn().insert((A(4), B(1))).id();
let e5 = world.spawn().insert((A(5), B(1))).id();
let e1 = world.spawn(A(1)).id();
let e2 = world.spawn(A(2)).id();
let e3 = world.spawn(A(3)).id();
let e4 = world.spawn((A(4), B(1))).id();
let e5 = world.spawn((A(5), B(1))).id();
let results = Arc::new(Mutex::new(Vec::new()));
world
.query::<(Entity, &A)>()
@ -392,11 +370,11 @@ mod tests {
fn par_for_each_sparse() {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::new();
let e1 = world.spawn().insert(SparseStored(1)).id();
let e2 = world.spawn().insert(SparseStored(2)).id();
let e3 = world.spawn().insert(SparseStored(3)).id();
let e4 = world.spawn().insert((SparseStored(4), A(1))).id();
let e5 = world.spawn().insert((SparseStored(5), A(1))).id();
let e1 = world.spawn(SparseStored(1)).id();
let e2 = world.spawn(SparseStored(2)).id();
let e3 = world.spawn(SparseStored(3)).id();
let e4 = world.spawn((SparseStored(4), A(1))).id();
let e5 = world.spawn((SparseStored(5), A(1))).id();
let results = Arc::new(Mutex::new(Vec::new()));
world.query::<(Entity, &SparseStored)>().par_for_each(
&world,
@ -413,19 +391,16 @@ mod tests {
#[test]
fn query_missing_component() {
let mut world = World::new();
world.spawn().insert((TableStored("abc"), A(123)));
world.spawn().insert((TableStored("def"), A(456)));
world.spawn((TableStored("abc"), A(123)));
world.spawn((TableStored("def"), A(456)));
assert!(world.query::<(&B, &A)>().iter(&world).next().is_none());
}
#[test]
fn query_sparse_component() {
let mut world = World::new();
world.spawn().insert((TableStored("abc"), A(123)));
let f = world
.spawn()
.insert((TableStored("def"), A(456), B(1)))
.id();
world.spawn((TableStored("abc"), A(123)));
let f = world.spawn((TableStored("def"), A(456), B(1))).id();
let ents = world
.query::<(Entity, &B)>()
.iter(&world)
@ -437,8 +412,8 @@ mod tests {
#[test]
fn query_filter_with() {
let mut world = World::new();
world.spawn().insert((A(123), B(1)));
world.spawn().insert(A(456));
world.spawn((A(123), B(1)));
world.spawn(A(456));
let result = world
.query_filtered::<&A, With<B>>()
.iter(&world)
@ -450,8 +425,8 @@ mod tests {
#[test]
fn query_filter_with_for_each() {
let mut world = World::new();
world.spawn().insert((A(123), B(1)));
world.spawn().insert(A(456));
world.spawn((A(123), B(1)));
world.spawn(A(456));
let mut results = Vec::new();
world
@ -464,8 +439,8 @@ mod tests {
fn query_filter_with_sparse() {
let mut world = World::new();
world.spawn().insert((A(123), SparseStored(321)));
world.spawn().insert(A(456));
world.spawn((A(123), SparseStored(321)));
world.spawn(A(456));
let result = world
.query_filtered::<&A, With<SparseStored>>()
.iter(&world)
@ -478,8 +453,8 @@ mod tests {
fn query_filter_with_sparse_for_each() {
let mut world = World::new();
world.spawn().insert((A(123), SparseStored(321)));
world.spawn().insert(A(456));
world.spawn((A(123), SparseStored(321)));
world.spawn(A(456));
let mut results = Vec::new();
world
.query_filtered::<&A, With<SparseStored>>()
@ -490,8 +465,8 @@ mod tests {
#[test]
fn query_filter_without() {
let mut world = World::new();
world.spawn().insert((A(123), B(321)));
world.spawn().insert(A(456));
world.spawn((A(123), B(321)));
world.spawn(A(456));
let result = world
.query_filtered::<&A, Without<B>>()
.iter(&world)
@ -503,13 +478,10 @@ mod tests {
#[test]
fn query_optional_component_table() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world
.spawn()
.insert((TableStored("def"), A(456), B(1)))
.id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456), B(1))).id();
// this should be skipped
world.spawn().insert(TableStored("abc"));
world.spawn(TableStored("abc"));
let ents = world
.query::<(Entity, Option<&B>, &A)>()
.iter(&world)
@ -522,13 +494,12 @@ mod tests {
fn query_optional_component_sparse() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world
.spawn()
.insert((TableStored("def"), A(456), SparseStored(1)))
.spawn((TableStored("def"), A(456), SparseStored(1)))
.id();
// // this should be skipped
// SparseStored(1).spawn().insert("abc");
// SparseStored(1).spawn("abc");
let ents = world
.query::<(Entity, Option<&SparseStored>, &A)>()
.iter(&world)
@ -544,10 +515,10 @@ mod tests {
fn query_optional_component_sparse_no_match() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let f = world.spawn().insert((TableStored("def"), A(456))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
let f = world.spawn((TableStored("def"), A(456))).id();
// // this should be skipped
world.spawn().insert(TableStored("abc"));
world.spawn(TableStored("abc"));
let ents = world
.query::<(Entity, Option<&SparseStored>, &A)>()
.iter(&world)
@ -559,16 +530,8 @@ mod tests {
#[test]
fn add_remove_components() {
let mut world = World::new();
let e1 = world
.spawn()
.insert(A(1))
.insert((B(3), TableStored("abc")))
.id();
let e2 = world
.spawn()
.insert(A(2))
.insert((B(4), TableStored("xyz")))
.id();
let e1 = world.spawn((A(1), B(3), TableStored("abc"))).id();
let e2 = world.spawn((A(2), B(4), TableStored("xyz"))).id();
assert_eq!(
world
@ -631,7 +594,7 @@ mod tests {
};
for _ in 0..to {
entities.push(world.spawn().insert(B(0)).id());
entities.push(world.spawn(B(0)).id());
}
for (i, entity) in entities.iter().cloned().enumerate() {
@ -649,7 +612,7 @@ mod tests {
let mut entities = Vec::with_capacity(1000);
for _ in 0..4 {
entities.push(world.spawn().insert(A(2)).id());
entities.push(world.spawn(A(2)).id());
}
for (i, entity) in entities.iter().cloned().enumerate() {
@ -667,7 +630,7 @@ mod tests {
#[test]
fn remove_missing() {
let mut world = World::new();
let e = world.spawn().insert((TableStored("abc"), A(123))).id();
let e = world.spawn((TableStored("abc"), A(123))).id();
assert!(world.entity_mut(e).remove::<B>().is_none());
}
@ -687,12 +650,9 @@ mod tests {
#[test]
fn query_get() {
let mut world = World::new();
let a = world.spawn().insert((TableStored("abc"), A(123))).id();
let b = world.spawn().insert((TableStored("def"), A(456))).id();
let c = world
.spawn()
.insert((TableStored("ghi"), A(789), B(1)))
.id();
let a = world.spawn((TableStored("abc"), A(123))).id();
let b = world.spawn((TableStored("def"), A(456))).id();
let c = world.spawn((TableStored("ghi"), A(789), B(1))).id();
let mut i32_query = world.query::<&A>();
assert_eq!(i32_query.get(&world, a).unwrap().0, 123);
@ -709,8 +669,8 @@ mod tests {
fn remove_tracking() {
let mut world = World::new();
let a = world.spawn().insert((SparseStored(0), A(123))).id();
let b = world.spawn().insert((SparseStored(1), A(123))).id();
let a = world.spawn((SparseStored(0), A(123))).id();
let b = world.spawn((SparseStored(1), A(123))).id();
world.entity_mut(a).despawn();
assert_eq!(
@ -756,8 +716,8 @@ mod tests {
);
// TODO: uncomment when world.clear() is implemented
// let c = world.spawn().insert(("abc", 123)).id();
// let d = world.spawn().insert(("abc", 123)).id();
// let c = world.spawn(("abc", 123)).id();
// let d = world.spawn(("abc", 123)).id();
// world.clear();
// assert_eq!(
// world.removed::<i32>(),
@ -779,7 +739,7 @@ mod tests {
#[test]
fn added_tracking() {
let mut world = World::new();
let a = world.spawn().insert(A(123)).id();
let a = world.spawn(A(123)).id();
assert_eq!(world.query::<&A>().iter(&world).count(), 1);
assert_eq!(
@ -829,7 +789,7 @@ mod tests {
#[test]
fn added_queries() {
let mut world = World::default();
let e1 = world.spawn().insert(A(0)).id();
let e1 = world.spawn(A(0)).id();
fn get_added<Com: Component>(world: &mut World) -> Vec<Entity> {
world
@ -845,7 +805,7 @@ mod tests {
world.clear_trackers();
assert!(get_added::<A>(&mut world).is_empty());
let e2 = world.spawn().insert((A(1), B(1))).id();
let e2 = world.spawn((A(1), B(1))).id();
assert_eq!(get_added::<A>(&mut world), vec![e2]);
assert_eq!(get_added::<B>(&mut world), vec![e2]);
@ -859,10 +819,10 @@ mod tests {
#[test]
fn changed_trackers() {
let mut world = World::default();
let e1 = world.spawn().insert((A(0), B(0))).id();
let e2 = world.spawn().insert((A(0), B(0))).id();
let e3 = world.spawn().insert((A(0), B(0))).id();
world.spawn().insert((A(0), B(0)));
let e1 = world.spawn((A(0), B(0))).id();
let e2 = world.spawn((A(0), B(0))).id();
let e3 = world.spawn((A(0), B(0))).id();
world.spawn((A(0), B(0)));
world.clear_trackers();
@ -914,7 +874,7 @@ mod tests {
assert!(get_filtered::<Changed<A>>(&mut world).is_empty());
let e4 = world.spawn().id();
let e4 = world.spawn_empty().id();
world.entity_mut(e4).insert(A(0));
assert_eq!(get_filtered::<Changed<A>>(&mut world), vec![e4]);
@ -938,7 +898,7 @@ mod tests {
#[test]
fn empty_spawn() {
let mut world = World::default();
let e = world.spawn().id();
let e = world.spawn_empty().id();
let mut e_mut = world.entity_mut(e);
e_mut.insert(A(0));
assert_eq!(e_mut.get::<A>().unwrap(), &A(0));
@ -957,7 +917,7 @@ mod tests {
#[test]
fn changed_query() {
let mut world = World::default();
let e1 = world.spawn().insert((A(0), B(0))).id();
let e1 = world.spawn((A(0), B(0))).id();
fn get_changed(world: &mut World) -> Vec<Entity> {
world
@ -1075,7 +1035,7 @@ mod tests {
#[test]
fn remove_intersection() {
let mut world = World::default();
let e1 = world.spawn().insert((A(1), B(1), TableStored("a"))).id();
let e1 = world.spawn((A(1), B(1), TableStored("a"))).id();
let mut e = world.entity_mut(e1);
assert_eq!(e.get::<TableStored>(), Some(&TableStored("a")));
@ -1113,9 +1073,9 @@ mod tests {
#[test]
fn remove_bundle() {
let mut world = World::default();
world.spawn().insert((A(1), B(1), TableStored("1")));
let e2 = world.spawn().insert((A(2), B(2), TableStored("2"))).id();
world.spawn().insert((A(3), B(3), TableStored("3")));
world.spawn((A(1), B(1), TableStored("1")));
let e2 = world.spawn((A(2), B(2), TableStored("2"))).id();
world.spawn((A(3), B(3), TableStored("3")));
let mut query = world.query::<(&B, &TableStored)>();
let results = query
@ -1179,8 +1139,8 @@ mod tests {
#[test]
fn trackers_query() {
let mut world = World::default();
let e1 = world.spawn().insert((A(0), B(0))).id();
world.spawn().insert(B(0));
let e1 = world.spawn((A(0), B(0))).id();
world.spawn(B(0));
let mut trackers_query = world.query::<Option<ChangeTrackers<A>>>();
let trackers = trackers_query.iter(&world).collect::<Vec<_>>();
@ -1203,10 +1163,10 @@ mod tests {
#[test]
fn exact_size_query() {
let mut world = World::default();
world.spawn().insert((A(0), B(0)));
world.spawn().insert((A(0), B(0)));
world.spawn().insert((A(0), B(0), C));
world.spawn().insert(C);
world.spawn((A(0), B(0)));
world.spawn((A(0), B(0)));
world.spawn((A(0), B(0), C));
world.spawn(C);
let mut query = world.query::<(&A, &B)>();
assert_eq!(query.iter(&world).len(), 3);
@ -1216,7 +1176,7 @@ mod tests {
#[should_panic]
fn duplicate_components_panic() {
let mut world = World::new();
world.spawn().insert((A(1), A(2)));
world.spawn((A(1), A(2)));
}
#[test]
@ -1308,7 +1268,7 @@ mod tests {
let (dropck1, dropped1) = DropCk::new_pair();
let (dropck2, dropped2) = DropCk::new_pair();
let mut world = World::default();
world.spawn().insert(dropck1).insert(dropck2);
world.spawn(dropck1).insert(dropck2);
assert_eq!(dropped1.load(Ordering::Relaxed), 1);
assert_eq!(dropped2.load(Ordering::Relaxed), 0);
drop(world);
@ -1323,8 +1283,7 @@ mod tests {
let mut world = World::default();
world
.spawn()
.insert(DropCkSparse(dropck1))
.spawn(DropCkSparse(dropck1))
.insert(DropCkSparse(dropck2));
assert_eq!(dropped1.load(Ordering::Relaxed), 1);
assert_eq!(dropped2.load(Ordering::Relaxed), 0);
@ -1338,8 +1297,8 @@ mod tests {
let mut world = World::default();
world.insert_resource(A(0));
world.spawn().insert(A(1));
world.spawn().insert(SparseStored(1));
world.spawn(A(1));
world.spawn(SparseStored(1));
let mut q1 = world.query::<&A>();
let mut q2 = world.query::<&SparseStored>();
@ -1385,12 +1344,12 @@ mod tests {
};
}
world.spawn().insert((A(1), B(1), C));
world.spawn().insert((A(1), C));
world.spawn().insert((A(1), B(1)));
world.spawn().insert((B(1), C));
world.spawn().insert(A(1));
world.spawn().insert(C);
world.spawn((A(1), B(1), C));
world.spawn((A(1), C));
world.spawn((A(1), B(1)));
world.spawn((B(1), C));
world.spawn(A(1));
world.spawn(C);
assert_eq!(2, query_min_size![(), (With<A>, Without<B>)],);
assert_eq!(3, query_min_size![&B, Or<(With<A>, With<C>)>],);
assert_eq!(1, query_min_size![&B, (With<A>, With<C>)],);
@ -1411,8 +1370,8 @@ mod tests {
let mut world_a = World::default();
let mut world_b = World::default();
let e1 = world_a.spawn().insert(A(1)).id();
let e2 = world_a.spawn().insert(A(2)).id();
let e1 = world_a.spawn(A(1)).id();
let e2 = world_a.spawn(A(2)).id();
let e3 = world_a.entities().reserve_entity();
world_a.flush();
@ -1422,7 +1381,7 @@ mod tests {
.reserve_entities(world_a_max_entities as u32);
world_b.entities.flush_as_invalid();
let e4 = world_b.spawn().insert(A(4)).id();
let e4 = world_b.spawn(A(4)).id();
assert_eq!(
e4,
Entity {
@ -1535,7 +1494,7 @@ mod tests {
#[test]
fn insert_or_spawn_batch() {
let mut world = World::default();
let e0 = world.spawn().insert(A(0)).id();
let e0 = world.spawn(A(0)).id();
let e1 = Entity::from_raw(1);
let values = vec![(e0, (B(0), C)), (e1, (B(1), C))];
@ -1572,9 +1531,9 @@ mod tests {
#[test]
fn insert_or_spawn_batch_invalid() {
let mut world = World::default();
let e0 = world.spawn().insert(A(0)).id();
let e0 = world.spawn(A(0)).id();
let e1 = Entity::from_raw(1);
let e2 = world.spawn().id();
let e2 = world.spawn_empty().id();
let invalid_e2 = Entity {
generation: 1,
id: e2.id,

View file

@ -43,8 +43,8 @@ mod tests {
#[test]
fn query() {
let mut world = World::new();
world.spawn().insert((A(1), B(1)));
world.spawn().insert(A(2));
world.spawn((A(1), B(1)));
world.spawn(A(2));
let values = world.query::<&A>().iter(&world).collect::<Vec<&A>>();
assert_eq!(values, vec![&A(1), &A(2)]);
@ -127,24 +127,24 @@ count(): {count}"#
}
let mut world = World::new();
world.spawn().insert((A(1), B(1)));
world.spawn().insert(A(2));
world.spawn().insert(A(3));
world.spawn((A(1), B(1)));
world.spawn(A(2));
world.spawn(A(3));
assert_all_sizes_equal::<&A, With<B>>(&mut world, 1);
assert_all_sizes_equal::<&A, Without<B>>(&mut world, 2);
let mut world = World::new();
world.spawn().insert((A(1), B(1), C(1)));
world.spawn().insert((A(2), B(2)));
world.spawn().insert((A(3), B(3)));
world.spawn().insert((A(4), C(4)));
world.spawn().insert((A(5), C(5)));
world.spawn().insert((A(6), C(6)));
world.spawn().insert(A(7));
world.spawn().insert(A(8));
world.spawn().insert(A(9));
world.spawn().insert(A(10));
world.spawn((A(1), B(1), C(1)));
world.spawn((A(2), B(2)));
world.spawn((A(3), B(3)));
world.spawn((A(4), C(4)));
world.spawn((A(5), C(5)));
world.spawn((A(6), C(6)));
world.spawn(A(7));
world.spawn(A(8));
world.spawn(A(9));
world.spawn(A(10));
// With/Without for B and C
assert_all_sizes_equal::<&A, With<B>>(&mut world, 3);
@ -167,7 +167,7 @@ count(): {count}"#
assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 6);
for i in 11..14 {
world.spawn().insert((A(i), D(i)));
world.spawn((A(i), D(i)));
}
assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 9);
@ -175,7 +175,7 @@ count(): {count}"#
// a fair amount of entities
for i in 14..20 {
world.spawn().insert((C(i), D(i)));
world.spawn((C(i), D(i)));
}
assert_all_sizes_equal::<Entity, (With<C>, With<D>)>(&mut world, 6);
}
@ -184,10 +184,10 @@ count(): {count}"#
fn query_iter_combinations() {
let mut world = World::new();
world.spawn().insert((A(1), B(1)));
world.spawn().insert(A(2));
world.spawn().insert(A(3));
world.spawn().insert(A(4));
world.spawn((A(1), B(1)));
world.spawn(A(2));
world.spawn(A(3));
world.spawn(A(4));
let values: Vec<[&A; 2]> = world.query::<&A>().iter_combinations(&world).collect();
assert_eq!(
@ -247,10 +247,10 @@ count(): {count}"#
let mut world = World::new();
world.spawn().insert((A(1), B(1)));
world.spawn().insert(A(2));
world.spawn().insert(A(3));
world.spawn().insert(A(4));
world.spawn((A(1), B(1)));
world.spawn(A(2));
world.spawn(A(3));
world.spawn(A(4));
let mut a_wout_b = world.query_filtered::<&A, Without<B>>();
let values: HashSet<[&A; 2]> = a_wout_b.iter_combinations(&world).collect();
@ -302,28 +302,28 @@ count(): {count}"#
// Check if Added<T>, Changed<T> works
let mut world = World::new();
world.spawn().insert((A(1), B(1)));
world.spawn().insert((A(2), B(2)));
world.spawn().insert((A(3), B(3)));
world.spawn().insert((A(4), B(4)));
world.spawn((A(1), B(1)));
world.spawn((A(2), B(2)));
world.spawn((A(3), B(3)));
world.spawn((A(4), B(4)));
let mut query_added = world.query_filtered::<&A, Added<A>>();
world.clear_trackers();
world.spawn().insert(A(5));
world.spawn(A(5));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 0);
world.clear_trackers();
world.spawn().insert(A(6));
world.spawn().insert(A(7));
world.spawn(A(6));
world.spawn(A(7));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 1);
world.clear_trackers();
world.spawn().insert(A(8));
world.spawn().insert(A(9));
world.spawn().insert(A(10));
world.spawn(A(8));
world.spawn(A(9));
world.spawn(A(10));
assert_eq!(query_added.iter_combinations::<2>(&world).count(), 3);
@ -384,8 +384,8 @@ count(): {count}"#
fn multi_storage_query() {
let mut world = World::new();
world.spawn().insert((Sparse(1), B(2)));
world.spawn().insert(Sparse(2));
world.spawn((Sparse(1), B(2)));
world.spawn(Sparse(2));
let values = world
.query::<&Sparse>()
@ -405,9 +405,9 @@ count(): {count}"#
fn any_query() {
let mut world = World::new();
world.spawn().insert((A(1), B(2)));
world.spawn().insert(A(2));
world.spawn().insert(C(3));
world.spawn((A(1), B(2)));
world.spawn(A(2));
world.spawn(C(3));
let values: Vec<(Option<&A>, Option<&B>)> =
world.query::<AnyOf<(&A, &B)>>().iter(&world).collect();
@ -436,26 +436,26 @@ count(): {count}"#
fn derived_worldqueries() {
let mut world = World::new();
world.spawn().insert((A(10), B(18), C(3), Sparse(4)));
world.spawn((A(10), B(18), C(3), Sparse(4)));
world.spawn().insert((A(101), B(148), C(13)));
world.spawn().insert((A(51), B(46), Sparse(72)));
world.spawn().insert((A(398), C(6), Sparse(9)));
world.spawn().insert((B(11), C(28), Sparse(92)));
world.spawn((A(101), B(148), C(13)));
world.spawn((A(51), B(46), Sparse(72)));
world.spawn((A(398), C(6), Sparse(9)));
world.spawn((B(11), C(28), Sparse(92)));
world.spawn().insert((C(18348), Sparse(101)));
world.spawn().insert((B(839), Sparse(5)));
world.spawn().insert((B(6721), C(122)));
world.spawn().insert((A(220), Sparse(63)));
world.spawn().insert((A(1092), C(382)));
world.spawn().insert((A(2058), B(3019)));
world.spawn((C(18348), Sparse(101)));
world.spawn((B(839), Sparse(5)));
world.spawn((B(6721), C(122)));
world.spawn((A(220), Sparse(63)));
world.spawn((A(1092), C(382)));
world.spawn((A(2058), B(3019)));
world.spawn().insert((B(38), C(8), Sparse(100)));
world.spawn().insert((A(111), C(52), Sparse(1)));
world.spawn().insert((A(599), B(39), Sparse(13)));
world.spawn().insert((A(55), B(66), C(77)));
world.spawn((B(38), C(8), Sparse(100)));
world.spawn((A(111), C(52), Sparse(1)));
world.spawn((A(599), B(39), Sparse(13)));
world.spawn((A(55), B(66), C(77)));
world.spawn();
world.spawn_empty();
{
#[derive(WorldQuery)]
@ -619,10 +619,10 @@ count(): {count}"#
#[test]
fn many_entities() {
let mut world = World::new();
world.spawn().insert((A(0), B(0)));
world.spawn().insert((A(0), B(0)));
world.spawn().insert(A(0));
world.spawn().insert(B(0));
world.spawn((A(0), B(0)));
world.spawn((A(0), B(0)));
world.spawn(A(0));
world.spawn(B(0));
{
fn system(has_a: Query<Entity, With<A>>, has_a_and_b: Query<(&A, &B)>) {
assert_eq!(has_a_and_b.iter_many(&has_a).count(), 2);
@ -663,7 +663,7 @@ count(): {count}"#
struct Foo;
let mut world = World::new();
let e = world.spawn().insert(Foo).id();
let e = world.spawn(Foo).id();
// state
let mut q = world.query::<&mut Foo>();

View file

@ -221,10 +221,10 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
/// struct A(usize);
///
/// let mut world = World::new();
/// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn().insert(A(i)).id()).collect();
/// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
/// let entities: [Entity; 3] = entity_vec.try_into().unwrap();
///
/// world.spawn().insert(A(73));
/// world.spawn(A(73));
///
/// let mut query_state = world.query::<&A>();
///
@ -288,10 +288,10 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
///
/// let mut world = World::new();
///
/// let entities: Vec<Entity> = (0..3).map(|i|world.spawn().insert(A(i)).id()).collect();
/// let entities: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
/// let entities: [Entity; 3] = entities.try_into().unwrap();
///
/// world.spawn().insert(A(73));
/// world.spawn(A(73));
///
/// let mut query_state = world.query::<&mut A>();
///
@ -306,7 +306,7 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
///
/// let wrong_entity = Entity::from_raw(57);
/// let invalid_entity = world.spawn().id();
/// let invalid_entity = world.spawn_empty().id();
///
/// assert_eq!(query_state.get_many_mut(&mut world, [wrong_entity]).unwrap_err(), QueryEntityError::NoSuchEntity(wrong_entity));
/// assert_eq!(query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err(), QueryEntityError::QueryDoesNotMatch(invalid_entity));
@ -1225,7 +1225,7 @@ mod tests {
fn get_many_unchecked_manual_uniqueness() {
let mut world = World::new();
let entities: Vec<Entity> = (0..10).map(|_| world.spawn().id()).collect();
let entities: Vec<Entity> = (0..10).map(|_| world.spawn_empty().id()).collect();
let query_state = world.query::<Entity>();

View file

@ -320,7 +320,7 @@ mod tests {
fn one_of_everything() {
let mut world = World::new();
world.insert_resource(R);
world.spawn().insert(A);
world.spawn(A);
world.init_resource::<Events<E>>();
let mut test_stage = SystemStage::parallel();
@ -339,7 +339,7 @@ mod tests {
fn read_only() {
let mut world = World::new();
world.insert_resource(R);
world.spawn().insert(A);
world.spawn(A);
world.init_resource::<Events<E>>();
let mut test_stage = SystemStage::parallel();
@ -366,7 +366,7 @@ mod tests {
fn read_world() {
let mut world = World::new();
world.insert_resource(R);
world.spawn().insert(A);
world.spawn(A);
world.init_resource::<Events<E>>();
let mut test_stage = SystemStage::parallel();
@ -412,7 +412,7 @@ mod tests {
#[test]
fn components() {
let mut world = World::new();
world.spawn().insert(A);
world.spawn(A);
let mut test_stage = SystemStage::parallel();
test_stage
@ -428,7 +428,7 @@ mod tests {
#[ignore = "Known failing but fix is non-trivial: https://github.com/bevyengine/bevy/issues/4381"]
fn filtered_components() {
let mut world = World::new();
world.spawn().insert(A);
world.spawn(A);
let mut test_stage = SystemStage::parallel();
test_stage
@ -461,7 +461,7 @@ mod tests {
fn exclusive() {
let mut world = World::new();
world.insert_resource(R);
world.spawn().insert(A);
world.spawn(A);
world.init_resource::<Events<E>>();
let mut test_stage = SystemStage::parallel();

View file

@ -468,7 +468,7 @@ mod tests {
#[test]
fn queries() {
let mut world = World::new();
world.spawn().insert(W(0usize));
world.spawn(W(0usize));
fn wants_mut(_: Query<&mut W<usize>>) {}
fn wants_ref(_: Query<&W<usize>>) {}
let mut stage = SystemStage::parallel()
@ -493,7 +493,7 @@ mod tests {
stage.run(&mut world);
assert_eq!(receive_events(&world), vec![StartedSystems(2),]);
let mut world = World::new();
world.spawn().insert((W(0usize), W(0u32), W(0f32)));
world.spawn((W(0usize), W(0u32), W(0f32)));
fn wants_mut_usize(_: Query<(&mut W<usize>, &W<f32>)>) {}
fn wants_mut_u32(_: Query<(&mut W<u32>, &W<f32>)>) {}
let mut stage = SystemStage::parallel()
@ -506,7 +506,7 @@ mod tests {
#[test]
fn world() {
let mut world = World::new();
world.spawn().insert(W(0usize));
world.spawn(W(0usize));
fn wants_world(_: &World) {}
fn wants_mut(_: Query<&mut W<usize>>) {}
let mut stage = SystemStage::parallel()

View file

@ -1477,7 +1477,7 @@ mod tests {
world.insert_resource(R(0));
let mut stage = SystemStage::single(query_count_system);
let entity = world.spawn().insert(()).id();
let entity = world.spawn_empty().id();
stage.run(&mut world);
assert_eq!(world.resource::<R>().0, 1);
@ -1497,7 +1497,7 @@ mod tests {
let mut stage = SystemStage::parallel();
stage.add_system(query_count_system);
let entity = world.spawn().insert(()).id();
let entity = world.spawn_empty().id();
stage.run(&mut world);
assert_eq!(world.resource::<R>().0, 1);
@ -1522,7 +1522,7 @@ mod tests {
}
fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn_bundle(Foo);
commands.spawn(Foo);
}
fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) {
@ -1564,7 +1564,7 @@ mod tests {
}
fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn_bundle(Foo);
commands.spawn(Foo);
}
fn count_entities(query: Query<&Foo>, mut res: ResMut<EntityCount>) {

View file

@ -153,7 +153,7 @@ mod test {
impl Command for SpawnCommand {
fn write(self, world: &mut World) {
world.spawn();
world.spawn_empty();
}
}

View file

@ -125,7 +125,7 @@ impl<'w, 's> Commands<'w, 's> {
/// Pushes a [`Command`] to the queue for creating a new empty [`Entity`],
/// and returns its corresponding [`EntityCommands`].
///
/// See [`World::spawn`] for more details.
/// See [`World::spawn_empty`] for more details.
///
/// # Example
///
@ -141,10 +141,10 @@ impl<'w, 's> Commands<'w, 's> {
///
/// fn example_system(mut commands: Commands) {
/// // Create a new empty entity and retrieve its id.
/// let empty_entity = commands.spawn().id();
/// let empty_entity = commands.spawn_empty().id();
///
/// // Create another empty entity, then add some component to it
/// commands.spawn()
/// commands.spawn_empty()
/// // adds a new component bundle to the entity
/// .insert((Strength(1), Agility(2)))
/// // adds a single component to the entity
@ -155,9 +155,9 @@ impl<'w, 's> Commands<'w, 's> {
///
/// # See also
///
/// - [`spawn_bundle`](Self::spawn_bundle) to spawn an entity with a bundle.
/// - [`spawn`](Self::spawn) to spawn an entity with a bundle.
/// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each.
pub fn spawn<'a>(&'a mut self) -> EntityCommands<'w, 's, 'a> {
pub fn spawn_empty<'a>(&'a mut self) -> EntityCommands<'w, 's, 'a> {
let entity = self.entities.reserve_entity();
EntityCommands {
entity,
@ -210,16 +210,19 @@ impl<'w, 's> Commands<'w, 's> {
/// }
///
/// fn example_system(mut commands: Commands) {
/// // Create a new entity with a single component.
/// commands.spawn(Component1);
///
/// // Create a new entity with a component bundle.
/// commands.spawn_bundle(ExampleBundle {
/// commands.spawn(ExampleBundle {
/// a: Component1,
/// b: Component2,
/// });
///
/// commands
/// // Create a new entity with two components using a "tuple bundle".
/// .spawn_bundle((Component1, Component2))
/// // spawn_bundle returns a builder, so you can insert more bundles like this:
/// .spawn((Component1, Component2))
/// // `spawn returns a builder, so you can insert more bundles like this:
/// .insert((Strength(1), Agility(2)))
/// // or insert single components like this:
/// .insert(Label("hello world"));
@ -229,10 +232,20 @@ impl<'w, 's> Commands<'w, 's> {
///
/// # See also
///
/// - [`spawn`](Self::spawn) to just spawn an entity without any component.
/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.
/// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each.
pub fn spawn<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> {
let mut e = self.spawn_empty();
e.insert(bundle);
e
}
#[deprecated(
since = "0.9.0",
note = "Use `spawn` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn spawn_bundle<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> {
let mut e = self.spawn();
let mut e = self.spawn_empty();
e.insert(bundle);
e
}
@ -257,7 +270,7 @@ impl<'w, 's> Commands<'w, 's> {
///
/// fn example_system(mut commands: Commands) {
/// // Create a new, empty entity
/// let entity = commands.spawn().id();
/// let entity = commands.spawn_empty().id();
///
/// commands.entity(entity)
/// // adds a new component bundle to the entity
@ -299,7 +312,7 @@ impl<'w, 's> Commands<'w, 's> {
/// fn example_system(mut commands: Commands) {
/// // Create a new, empty entity
/// let entity = commands.spawn().id();
/// let entity = commands.spawn_empty().id();
///
/// // Get the entity if it still exists, which it will in this case
/// if let Some(mut entity_commands) = commands.get_entity(entity) {
@ -358,8 +371,8 @@ impl<'w, 's> Commands<'w, 's> {
///
/// # See also
///
/// - [`spawn`](Self::spawn) to just spawn an entity without any component.
/// - [`spawn_bundle`](Self::spawn_bundle) to spawn an entity with a bundle.
/// - [`spawn`](Self::spawn) to spawn an entity with a bundle.
/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.
pub fn spawn_batch<I>(&mut self, bundles_iter: I)
where
I: IntoIterator + Send + Sync + 'static,
@ -537,7 +550,7 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// # use bevy_ecs::prelude::*;
/// #
/// fn my_system(mut commands: Commands) {
/// let entity_id = commands.spawn().id();
/// let entity_id = commands.spawn_empty().id();
/// }
/// # bevy_ecs::system::assert_is_system(my_system);
/// ```
@ -725,7 +738,7 @@ where
T: Bundle,
{
fn write(self, world: &mut World) {
world.spawn().insert(self.bundle);
world.spawn(self.bundle);
}
}
@ -916,7 +929,7 @@ mod tests {
struct W<T>(T);
fn simple_command(world: &mut World) {
world.spawn().insert((W(0u32), W(42u64)));
world.spawn((W(0u32), W(42u64)));
}
#[test]
@ -924,7 +937,7 @@ mod tests {
let mut world = World::default();
let mut command_queue = CommandQueue::default();
let entity = Commands::new(&mut command_queue, &world)
.spawn_bundle((W(1u32), W(2u64)))
.spawn((W(1u32), W(2u64)))
.id();
command_queue.apply(&mut world);
assert!(world.entities().len() == 1);
@ -954,7 +967,7 @@ mod tests {
// set up a simple command using a closure that adds one additional entity
commands.add(|world: &mut World| {
world.spawn().insert((W(42u32), W(0u64)));
world.spawn((W(42u32), W(0u64)));
});
// set up a simple command using a function that adds one additional entity
@ -980,8 +993,7 @@ mod tests {
let sparse_dropck = SparseDropCk(sparse_dropck);
let entity = Commands::new(&mut command_queue, &world)
.spawn()
.insert((W(1u32), W(2u64), dense_dropck, sparse_dropck))
.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
.id();
command_queue.apply(&mut world);
let results_before = world

View file

@ -138,14 +138,14 @@ mod tests {
}
let mut stage = SystemStage::parallel().with_system(removal);
world.spawn().insert(Foo(0.0f32));
world.spawn(Foo(0.0f32));
world.insert_resource(Counter(0));
stage.run(&mut world);
stage.run(&mut world);
assert_eq!(world.resource::<Counter>().0, 1);
let mut stage = SystemStage::parallel().with_system(removal.exclusive_system());
world.spawn().insert(Foo(0.0f32));
world.spawn(Foo(0.0f32));
world.insert_resource(Counter(0));
stage.run(&mut world);
stage.run(&mut world);
@ -158,7 +158,7 @@ mod tests {
struct CountEntities(Vec<usize>);
fn spawn_entity(mut commands: crate::prelude::Commands) {
commands.spawn_bundle(Foo(0.0));
commands.spawn(Foo(0.0));
}
fn count_entities(query: Query<&Foo>, mut res: ResMut<CountEntities>) {

View file

@ -183,7 +183,7 @@ mod tests {
let mut system = IntoSystem::into_system(sys);
let mut world = World::new();
world.spawn().insert(A);
world.spawn(A);
system.initialize(&mut world);
system.run((), &mut world);
@ -245,10 +245,10 @@ mod tests {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert(A);
world.spawn().insert((A, B));
world.spawn().insert((A, C));
world.spawn().insert((A, D));
world.spawn(A);
world.spawn((A, B));
world.spawn((A, C));
world.spawn((A, D));
run_system(&mut world, query_system);
@ -276,7 +276,7 @@ mod tests {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert((A, B));
world.spawn((A, B));
run_system(&mut world, query_system);
@ -583,9 +583,9 @@ mod tests {
fn removal_tracking() {
let mut world = World::new();
let entity_to_despawn = world.spawn().insert(W(1)).id();
let entity_to_remove_w_from = world.spawn().insert(W(2)).id();
let spurious_entity = world.spawn().id();
let entity_to_despawn = world.spawn(W(1)).id();
let entity_to_remove_w_from = world.spawn(W(2)).id();
let spurious_entity = world.spawn_empty().id();
// Track which entities we want to operate on
#[derive(Resource)]
@ -626,8 +626,8 @@ mod tests {
world.clear_trackers();
// Then, try removing a component
world.spawn().insert(W(3));
world.spawn().insert(W(4));
world.spawn(W(3));
world.spawn(W(4));
world.entity_mut(entity_to_remove_w_from).remove::<W<i32>>();
fn validate_remove(
@ -654,7 +654,7 @@ mod tests {
fn world_collections_system() {
let mut world = World::default();
world.insert_resource(SystemRan::No);
world.spawn().insert((W(42), W(true)));
world.spawn((W(42), W(true)));
fn sys(
archetypes: &Archetypes,
components: &Components,
@ -728,7 +728,7 @@ mod tests {
}
let mut world = World::default();
world.spawn().insert(A).insert(C);
world.spawn(A).insert(C);
let mut without_filter = IntoSystem::into_system(without_filter);
without_filter.initialize(&mut world);
@ -797,7 +797,7 @@ mod tests {
let mut world = World::default();
world.insert_resource(A(42));
world.spawn().insert(B(7));
world.spawn(B(7));
let mut system_state: SystemState<(Res<A>, Query<&B>, ParamSet<(Query<&C>, Query<&D>)>)> =
SystemState::new(&mut world);
@ -820,7 +820,7 @@ mod tests {
let mut world = World::default();
world.insert_resource(A(42));
world.spawn().insert(B(7));
world.spawn(B(7));
let mut system_state: SystemState<(ResMut<A>, Query<&mut B>)> =
SystemState::new(&mut world);
@ -843,7 +843,7 @@ mod tests {
struct A(usize);
let mut world = World::default();
let entity = world.spawn().insert(A(1)).id();
let entity = world.spawn(A(1)).id();
let mut system_state: SystemState<Query<&A, Changed<A>>> = SystemState::new(&mut world);
{
@ -881,7 +881,7 @@ mod tests {
struct B(usize);
let mut world = World::default();
world.spawn().insert(A(1));
world.spawn(A(1));
let mut system_state = SystemState::<Query<&A>>::new(&mut world);
{
@ -893,7 +893,7 @@ mod tests {
);
}
world.spawn().insert((A(2), B(2)));
world.spawn((A(2), B(2)));
{
let query = system_state.get(&world);
assert_eq!(
@ -946,8 +946,8 @@ mod tests {
struct A(usize);
let mut world = World::default();
world.spawn().insert(A(1));
world.spawn().insert(A(2));
world.spawn(A(1));
world.spawn(A(2));
let mut system_state = SystemState::<Query<&mut A>>::new(&mut world);
{
@ -1113,24 +1113,22 @@ mod tests {
// add some entities with archetypes that should match and save their ids
expected_ids.insert(
world
.spawn()
.insert(A)
.spawn(A)
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
);
expected_ids.insert(
world
.spawn()
.insert((A, C))
.spawn((A, C))
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
);
// add some entities with archetypes that should not match
world.spawn().insert((A, B));
world.spawn().insert((B, C));
world.spawn((A, B));
world.spawn((B, C));
// update system and verify its accesses are correct
system.update_archetype_component_access(&world);
@ -1145,13 +1143,12 @@ mod tests {
// one more round
expected_ids.insert(
world
.spawn()
.insert((A, D))
.spawn((A, D))
.archetype()
.get_archetype_component_id(a_id)
.unwrap(),
);
world.spawn().insert((A, B, D));
world.spawn((A, B, D));
system.update_archetype_component_access(&world);
assert_eq!(
system
@ -1166,7 +1163,7 @@ mod tests {
fn commands_param_set() {
// Regression test for #4676
let mut world = World::new();
let entity = world.spawn().id();
let entity = world.spawn_empty().id();
run_system(
&mut world,
@ -1184,7 +1181,7 @@ mod tests {
#[test]
fn into_iter_impl() {
let mut world = World::new();
world.spawn().insert(W(42u32));
world.spawn(W(42u32));
run_system(&mut world, |mut q: Query<&mut W<u32>>| {
for mut a in &mut q {
assert_eq!(a.0, 42);

View file

@ -960,7 +960,7 @@ mod tests {
#[test]
fn entity_ref_get_by_id() {
let mut world = World::new();
let entity = world.spawn().insert(TestComponent(42)).id();
let entity = world.spawn(TestComponent(42)).id();
let component_id = world
.components()
.get_id(std::any::TypeId::of::<TestComponent>())
@ -977,7 +977,7 @@ mod tests {
#[test]
fn entity_mut_get_by_id() {
let mut world = World::new();
let entity = world.spawn().insert(TestComponent(42)).id();
let entity = world.spawn(TestComponent(42)).id();
let component_id = world
.components()
.get_id(std::any::TypeId::of::<TestComponent>())
@ -1006,7 +1006,7 @@ mod tests {
let invalid_component_id = ComponentId::new(usize::MAX);
let mut world = World::new();
let entity = world.spawn().id();
let entity = world.spawn_empty().id();
let entity = world.entity(entity);
assert!(entity.get_by_id(invalid_component_id).is_none());
}
@ -1016,7 +1016,7 @@ mod tests {
let invalid_component_id = ComponentId::new(usize::MAX);
let mut world = World::new();
let mut entity = world.spawn();
let mut entity = world.spawn_empty();
assert!(entity.get_by_id(invalid_component_id).is_none());
assert!(entity.get_mut_by_id(invalid_component_id).is_none());
}

View file

@ -211,10 +211,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
///
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let position = world.entity(entity).get::<Position>().unwrap();
/// assert_eq!(position.x, 0.0);
/// ```
@ -239,9 +236,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let mut entity_mut = world.entity_mut(entity);
/// let mut position = entity_mut.get_mut::<Position>().unwrap();
/// position.x = 1.0;
@ -294,7 +289,7 @@ impl World {
}
AllocAtWithoutReplacement::DidNotExist => {
// SAFETY: entity was just allocated
Some(unsafe { self.spawn_at_internal(entity) })
Some(unsafe { self.spawn_at_empty_internal(entity) })
}
AllocAtWithoutReplacement::ExistsWithWrongGeneration => None,
}
@ -314,10 +309,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
///
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let entity_ref = world.get_entity(entity).unwrap();
/// let position = entity_ref.get::<Position>().unwrap();
/// assert_eq!(position.x, 0.0);
@ -342,10 +334,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
///
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let mut entity_mut = world.get_entity_mut(entity).unwrap();
/// let mut position = entity_mut.get_mut::<Position>().unwrap();
/// position.x = 1.0;
@ -374,7 +363,7 @@ impl World {
/// struct Num(u32);
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// let entity = world.spawn_empty()
/// .insert(Position { x: 0.0, y: 0.0 }) // add a single component
/// .insert((Num(1), Label("hello"))) // add a bundle of components
/// .id();
@ -382,16 +371,98 @@ impl World {
/// let position = world.entity(entity).get::<Position>().unwrap();
/// assert_eq!(position.x, 0.0);
/// ```
pub fn spawn(&mut self) -> EntityMut {
pub fn spawn_empty(&mut self) -> EntityMut {
self.flush();
let entity = self.entities.alloc();
// SAFETY: entity was just allocated
unsafe { self.spawn_at_internal(entity) }
unsafe { self.spawn_at_empty_internal(entity) }
}
/// Spawns a new [`Entity`] with a given [`Bundle`] of [components](`Component`) and returns
/// a corresponding [`EntityMut`], which can be used to add components to the entity or
/// retrieve its id.
///
/// ```
/// use bevy_ecs::{bundle::Bundle, component::Component, world::World};
///
/// #[derive(Component)]
/// struct Position {
/// x: f32,
/// y: f32,
/// }
///
/// #[derive(Component)]
/// struct Velocity {
/// x: f32,
/// y: f32,
/// };
///
/// #[derive(Component)]
/// struct Name(&'static str);
///
/// #[derive(Bundle)]
/// struct PhysicsBundle {
/// position: Position,
/// velocity: Velocity,
/// }
///
/// let mut world = World::new();
///
/// // `spawn` can accept a single component:
/// world.spawn(Position { x: 0.0, y: 0.0 });
/// // It can also accept a tuple of components:
/// world.spawn((
/// Position { x: 0.0, y: 0.0 },
/// Velocity { x: 1.0, y: 1.0 },
/// ));
/// // Or it can accept a pre-defined Bundle of components:
/// world.spawn(PhysicsBundle {
/// position: Position { x: 2.0, y: 2.0 },
/// velocity: Velocity { x: 0.0, y: 4.0 },
/// });
///
/// let entity = world
/// // Tuples can also mix Bundles and Components
/// .spawn((
/// PhysicsBundle {
/// position: Position { x: 2.0, y: 2.0 },
/// velocity: Velocity { x: 0.0, y: 4.0 },
/// },
/// Name("Elaina Proctor"),
/// ))
/// // Calling id() will return the unique identifier for the spawned entity
/// .id();
/// let position = world.entity(entity).get::<Position>().unwrap();
/// assert_eq!(position.x, 2.0);
/// ```
pub fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityMut {
self.flush();
let entity = self.entities.alloc();
let entity_location = {
let bundle_info = self
.bundles
.init_info::<B>(&mut self.components, &mut self.storages);
let mut spawner = bundle_info.get_bundle_spawner(
&mut self.entities,
&mut self.archetypes,
&mut self.components,
&mut self.storages,
*self.change_tick.get_mut(),
);
// SAFETY: bundle's type matches `bundle_info`, entity is allocated but non-existent
unsafe { spawner.spawn_non_existent(entity, bundle) }
};
// SAFETY: entity and location are valid, as they were just created above
unsafe { EntityMut::new(self, entity, entity_location) }
}
/// # Safety
/// must be called on an entity that was just allocated
unsafe fn spawn_at_internal(&mut self, entity: Entity) -> EntityMut {
unsafe fn spawn_at_empty_internal(&mut self, entity: Entity) -> EntityMut {
let archetype = self.archetypes.empty_mut();
// PERF: consider avoiding allocating entities in the empty archetype unless needed
let table_row = self.storages.tables[archetype.table_id()].allocate(entity);
@ -448,9 +519,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let position = world.get::<Position>(entity).unwrap();
/// assert_eq!(position.x, 0.0);
/// ```
@ -471,9 +540,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// let mut position = world.get_mut::<Position>(entity).unwrap();
/// position.x = 1.0;
/// ```
@ -496,9 +563,7 @@ impl World {
/// }
///
/// let mut world = World::new();
/// let entity = world.spawn()
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
/// let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
/// assert!(world.despawn(entity));
/// assert!(world.get_entity(entity).is_none());
/// assert!(world.get::<Position>(entity).is_none());
@ -570,9 +635,9 @@ impl World {
/// struct Label(&'static str);
///
/// let mut world = World::new();
/// let a = world.spawn().insert((Order(2), Label("second"))).id();
/// let b = world.spawn().insert((Order(3), Label("third"))).id();
/// let c = world.spawn().insert((Order(1), Label("first"))).id();
/// let a = world.spawn((Order(2), Label("second"))).id();
/// let b = world.spawn((Order(3), Label("third"))).id();
/// let c = world.spawn((Order(1), Label("first"))).id();
/// let mut entities = world.query::<(Entity, &Order, &Label)>()
/// .iter(&world)
/// .collect::<Vec<_>>();
@ -601,8 +666,8 @@ impl World {
/// struct B;
///
/// let mut world = World::new();
/// let e1 = world.spawn().insert(A).id();
/// let e2 = world.spawn().insert((A, B)).id();
/// let e1 = world.spawn(A).id();
/// let e2 = world.spawn((A, B)).id();
///
/// let mut query = world.query_filtered::<Entity, With<B>>();
/// let matching_entities = query.iter(&world).collect::<Vec<Entity>>();
@ -958,8 +1023,8 @@ impl World {
/// struct B(f32);
///
/// let mut world = World::new();
/// let e0 = world.spawn().id();
/// let e1 = world.spawn().id();
/// let e0 = world.spawn_empty().id();
/// let e1 = world.spawn_empty().id();
/// world.insert_or_spawn_batch(vec![
/// (e0, (A("a"), B(0.0))), // the first entity
/// (e1, (A("b"), B(1.0))), // the second entity
@ -1076,7 +1141,7 @@ impl World {
/// struct B(u32);
/// let mut world = World::new();
/// world.insert_resource(A(1));
/// let entity = world.spawn().insert(B(1)).id();
/// let entity = world.spawn(B(1)).id();
///
/// world.resource_scope(|world, mut a: Mut<A>| {
/// let b = world.get_mut::<B>(entity).unwrap();
@ -1663,7 +1728,7 @@ mod tests {
let res = panic::catch_unwind(|| {
let mut world = World::new();
world
.spawn()
.spawn_empty()
.insert(helper.make_component(true, 0))
.insert(helper.make_component(false, 1));
@ -1782,13 +1847,13 @@ mod tests {
#[test]
fn inspect_entity_components() {
let mut world = World::new();
let ent0 = world.spawn().insert((Foo, Bar, Baz)).id();
let ent1 = world.spawn().insert((Foo, Bar)).id();
let ent2 = world.spawn().insert((Bar, Baz)).id();
let ent3 = world.spawn().insert((Foo, Baz)).id();
let ent4 = world.spawn().insert(Foo).id();
let ent5 = world.spawn().insert(Bar).id();
let ent6 = world.spawn().insert(Baz).id();
let ent0 = world.spawn((Foo, Bar, Baz)).id();
let ent1 = world.spawn((Foo, Bar)).id();
let ent2 = world.spawn((Bar, Baz)).id();
let ent3 = world.spawn((Foo, Baz)).id();
let ent4 = world.spawn(Foo).id();
let ent5 = world.spawn(Bar).id();
let ent6 = world.spawn(Baz).id();
fn to_type_ids(component_infos: Vec<&ComponentInfo>) -> HashSet<Option<TypeId>> {
component_infos

View file

@ -8,7 +8,7 @@ struct B;
fn main() {
let mut world = World::default();
let e = world.spawn().insert(A(Box::new(10_usize))).id();
let e = world.spawn(A(Box::new(10_usize))).id();
let mut e_mut = world.entity_mut(e);
@ -34,7 +34,7 @@ fn main() {
assert_eq!(gotten, &A(Box::new(14_usize))); // oops UB
}
let e = world.spawn().insert(A(Box::new(16_usize))).id();
let e = world.spawn(A(Box::new(16_usize))).id();
let mut e_mut = world.entity_mut(e);
{

View file

@ -6,7 +6,7 @@ struct Foo(u32);
fn main() {
let mut world = World::default();
let e = world.spawn().insert(Foo(10_u32)).id();
let e = world.spawn(Foo(10_u32)).id();
let mut system_state = SystemState::<Query<&mut Foo>>::new(&mut world);
{

View file

@ -6,8 +6,8 @@ struct A(usize);
fn main() {
let mut world = World::default();
world.spawn().insert(A(1));
world.spawn().insert(A(2));
world.spawn(A(1));
world.spawn(A(2));
let mut system_state = SystemState::<Query<&mut A>>::new(&mut world);
{

View file

@ -465,8 +465,7 @@ async fn load_gltf<'a, 'b>(
let mut entity_to_skin_index_map = HashMap::new();
world
.spawn()
.insert(SpatialBundle::VISIBLE_IDENTITY)
.spawn(SpatialBundle::VISIBLE_IDENTITY)
.with_children(|parent| {
for node in scene.nodes() {
let result = load_node(
@ -705,7 +704,7 @@ fn load_node(
) -> Result<(), GltfError> {
let transform = gltf_node.transform();
let mut gltf_error = None;
let mut node = world_builder.spawn_bundle(SpatialBundle::from(Transform::from_matrix(
let mut node = world_builder.spawn(SpatialBundle::from(Transform::from_matrix(
Mat4::from_cols_array_2d(&transform.matrix()),
)));
@ -787,7 +786,7 @@ fn load_node(
let material_asset_path =
AssetPath::new_ref(load_context.path(), Some(&material_label));
let mut mesh_entity = parent.spawn_bundle(PbrBundle {
let mut mesh_entity = parent.spawn(PbrBundle {
mesh: load_context.get_handle(mesh_asset_path),
material: load_context.get_handle(material_asset_path),
..Default::default()
@ -815,7 +814,7 @@ fn load_node(
if let Some(light) = gltf_node.light() {
match light.kind() {
gltf::khr_lights_punctual::Kind::Directional => {
let mut entity = parent.spawn_bundle(DirectionalLightBundle {
let mut entity = parent.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: Color::from(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for directional
@ -835,7 +834,7 @@ fn load_node(
}
}
gltf::khr_lights_punctual::Kind::Point => {
let mut entity = parent.spawn_bundle(PointLightBundle {
let mut entity = parent.spawn(PointLightBundle {
point_light: PointLight {
color: Color::from(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for point lights in
@ -861,7 +860,7 @@ fn load_node(
inner_cone_angle,
outer_cone_angle,
} => {
let mut entity = parent.spawn_bundle(SpotLightBundle {
let mut entity = parent.spawn(SpotLightBundle {
spot_light: SpotLight {
color: Color::from(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for spot lights in

View file

@ -186,15 +186,24 @@ pub struct ChildBuilder<'w, 's, 'a> {
impl<'w, 's, 'a> ChildBuilder<'w, 's, 'a> {
/// Spawns an entity with the given bundle and inserts it into the children defined by the [`ChildBuilder`]
#[deprecated(
since = "0.9.0",
note = "Use `spawn` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
pub fn spawn_bundle(&mut self, bundle: impl Bundle) -> EntityCommands<'w, 's, '_> {
let e = self.commands.spawn_bundle(bundle);
self.spawn(bundle)
}
/// Spawns an entity with the given bundle and inserts it into the children defined by the [`ChildBuilder`]
pub fn spawn(&mut self, bundle: impl Bundle) -> EntityCommands<'w, 's, '_> {
let e = self.commands.spawn(bundle);
self.push_children.children.push(e.id());
e
}
/// Spawns an [`Entity`] with no components and inserts it into the children defined by the [`ChildBuilder`] which adds the [`Parent`] component to it.
pub fn spawn(&mut self) -> EntityCommands<'w, 's, '_> {
let e = self.commands.spawn();
pub fn spawn_empty(&mut self) -> EntityCommands<'w, 's, '_> {
let e = self.commands.spawn_empty();
self.push_children.children.push(e.id());
e
}
@ -236,14 +245,14 @@ pub trait BuildChildren {
/// # struct MoreStuff;
/// #
/// # fn foo(mut commands: Commands) {
/// let mut parent_commands = commands.spawn();
/// let mut parent_commands = commands.spawn_empty();
/// let child_id = parent_commands.add_children(|parent| {
/// parent.spawn().id()
/// parent.spawn_empty().id()
/// });
///
/// parent_commands.insert(SomethingElse);
/// commands.entity(child_id).with_children(|parent| {
/// parent.spawn().insert(MoreStuff);
/// parent.spawn_bundle(MoreStuff);
/// });
/// # }
/// ```
@ -326,13 +335,9 @@ pub struct WorldChildBuilder<'w> {
impl<'w> WorldChildBuilder<'w> {
/// Spawns an entity with the given bundle and inserts it into the children defined by the [`WorldChildBuilder`]
pub fn spawn_bundle(&mut self, bundle: impl Bundle + Send + Sync + 'static) -> EntityMut<'_> {
pub fn spawn(&mut self, bundle: impl Bundle + Send + Sync + 'static) -> EntityMut<'_> {
let parent_entity = self.parent_entity();
let entity = self
.world
.spawn()
.insert((bundle, Parent(parent_entity)))
.id();
let entity = self.world.spawn((bundle, Parent(parent_entity))).id();
push_child_unchecked(self.world, parent_entity, entity);
self.current_entity = Some(entity);
if let Some(mut added) = self.world.get_resource_mut::<Events<HierarchyEvent>>() {
@ -344,10 +349,19 @@ impl<'w> WorldChildBuilder<'w> {
self.world.entity_mut(entity)
}
#[deprecated(
since = "0.9.0",
note = "Use `spawn` instead, which now accepts bundles, components, and tuples of bundles and components."
)]
/// Spawns an entity with the given bundle and inserts it into the children defined by the [`WorldChildBuilder`]
pub fn spawn_bundle(&mut self, bundle: impl Bundle + Send + Sync + 'static) -> EntityMut<'_> {
self.spawn(bundle)
}
/// Spawns an [`Entity`] with no components and inserts it into the children defined by the [`WorldChildBuilder`] which adds the [`Parent`] component to it.
pub fn spawn(&mut self) -> EntityMut<'_> {
pub fn spawn_empty(&mut self) -> EntityMut<'_> {
let parent_entity = self.parent_entity();
let entity = self.world.spawn().insert(Parent(parent_entity)).id();
let entity = self.world.spawn(Parent(parent_entity)).id();
push_child_unchecked(self.world, parent_entity, entity);
self.current_entity = Some(entity);
if let Some(mut added) = self.world.get_resource_mut::<Events<HierarchyEvent>>() {
@ -533,12 +547,12 @@ mod tests {
let mut queue = CommandQueue::default();
let mut commands = Commands::new(&mut queue, &world);
let parent = commands.spawn_bundle(C(1)).id();
let parent = commands.spawn(C(1)).id();
let children = commands.entity(parent).add_children(|parent| {
[
parent.spawn_bundle(C(2)).id(),
parent.spawn_bundle(C(3)).id(),
parent.spawn_bundle(C(4)).id(),
parent.spawn(C(2)).id(),
parent.spawn(C(3)).id(),
parent.spawn(C(4)).id(),
]
});
@ -661,7 +675,7 @@ mod tests {
#[test]
fn regression_push_children_same_archetype() {
let mut world = World::new();
let child = world.spawn().id();
world.spawn().push_children(&[child]);
let child = world.spawn_empty().id();
world.spawn_empty().push_children(&[child]);
}
}

View file

@ -165,35 +165,33 @@ mod tests {
let mut commands = Commands::new(&mut queue, &world);
commands
.spawn_bundle((N("Another parent".to_owned()), Idx(0)))
.spawn((N("Another parent".to_owned()), Idx(0)))
.with_children(|parent| {
parent.spawn_bundle((N("Another child".to_owned()), Idx(1)));
parent.spawn((N("Another child".to_owned()), Idx(1)));
});
// Create a grandparent entity which will _not_ be deleted
grandparent_entity = commands
.spawn_bundle((N("Grandparent".to_owned()), Idx(2)))
.id();
grandparent_entity = commands.spawn((N("Grandparent".to_owned()), Idx(2))).id();
commands.entity(grandparent_entity).with_children(|parent| {
// Add a child to the grandparent (the "parent"), which will get deleted
parent
.spawn_bundle((N("Parent, to be deleted".to_owned()), Idx(3)))
.spawn((N("Parent, to be deleted".to_owned()), Idx(3)))
// All descendents of the "parent" should also be deleted.
.with_children(|parent| {
parent
.spawn_bundle((N("First Child, to be deleted".to_owned()), Idx(4)))
.spawn((N("First Child, to be deleted".to_owned()), Idx(4)))
.with_children(|parent| {
// child
parent.spawn_bundle((
parent.spawn((
N("First grand child, to be deleted".to_owned()),
Idx(5),
));
});
parent.spawn_bundle((N("Second child, to be deleted".to_owned()), Idx(6)));
parent.spawn((N("Second child, to be deleted".to_owned()), Idx(6)));
});
});
commands.spawn_bundle((N("An innocent bystander".to_owned()), Idx(7)));
commands.spawn((N("An innocent bystander".to_owned()), Idx(7)));
}
queue.apply(&mut world);

View file

@ -85,7 +85,7 @@ use std::marker::PhantomData;
///
/// // Spawn an entity using `CustomMaterial`.
/// fn setup(mut commands: Commands, mut materials: ResMut<Assets<CustomMaterial>>, asset_server: Res<AssetServer>) {
/// commands.spawn_bundle(MaterialMeshBundle {
/// commands.spawn(MaterialMeshBundle {
/// material: materials.add(CustomMaterial {
/// color: Color::RED,
/// color_texture: asset_server.load("some_image.png"),

View file

@ -1013,7 +1013,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn_bundle((
.spawn((
ShadowView {
depth_texture_view,
pass_name: format!(
@ -1072,7 +1072,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn_bundle((
.spawn((
ShadowView {
depth_texture_view,
pass_name: format!("shadow pass spot light {}", light_index,),
@ -1155,7 +1155,7 @@ pub fn prepare_lights(
});
let view_light_entity = commands
.spawn_bundle((
.spawn((
ShadowView {
depth_texture_view,
pass_name: format!("shadow pass directional light {}", i),

View file

@ -428,34 +428,29 @@ mod test {
let root1 = app
.world
.spawn()
.insert((
.spawn((
Visibility { is_visible: false },
ComputedVisibility::default(),
))
.id();
let root1_child1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
let root1_child2 = app
.world
.spawn()
.insert((
.spawn((
Visibility { is_visible: false },
ComputedVisibility::default(),
))
.id();
let root1_child1_grandchild1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
let root1_child2_grandchild1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
app.world
@ -470,31 +465,26 @@ mod test {
let root2 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
let root2_child1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
let root2_child2 = app
.world
.spawn()
.insert((
.spawn((
Visibility { is_visible: false },
ComputedVisibility::default(),
))
.id();
let root2_child1_grandchild1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
let root2_child2_grandchild1 = app
.world
.spawn()
.insert((Visibility::default(), ComputedVisibility::default()))
.spawn((Visibility::default(), ComputedVisibility::default()))
.id();
app.world

View file

@ -94,7 +94,7 @@ impl DynamicScene {
// no corresponding entry.
let entity = *entity_map
.entry(bevy_ecs::entity::Entity::from_raw(scene_entity.entity))
.or_insert_with(|| world.spawn().id());
.or_insert_with(|| world.spawn_empty().id());
// Apply/ add each component to the given entity.
for component in &scene_entity.components {

View file

@ -54,7 +54,7 @@ impl Scene {
let entity = *instance_info
.entity_map
.entry(*scene_entity)
.or_insert_with(|| world.spawn().id());
.or_insert_with(|| world.spawn_empty().id());
for component_id in archetype.components() {
let component_info = self
.world

View file

@ -88,7 +88,7 @@ use crate::{
///
/// // Spawn an entity using `CustomMaterial`.
/// fn setup(mut commands: Commands, mut materials: ResMut<Assets<CustomMaterial>>, asset_server: Res<AssetServer>) {
/// commands.spawn_bundle(MaterialMesh2dBundle {
/// commands.spawn(MaterialMesh2dBundle {
/// material: materials.add(CustomMaterial {
/// color: Color::RED,
/// color_texture: asset_server.load("some_image.png"),

View file

@ -454,7 +454,7 @@ pub fn queue_sprites(
{
current_batch = new_batch;
current_image_size = Vec2::new(gpu_image.size.x, gpu_image.size.y);
current_batch_entity = commands.spawn_bundle((current_batch,)).id();
current_batch_entity = commands.spawn((current_batch,)).id();
image_bind_groups
.values

View file

@ -119,23 +119,20 @@ mod test {
schedule.add_stage(Update, update_stage);
// Root entity
world
.spawn()
.insert(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)));
world.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)));
let mut children = Vec::new();
world
.spawn()
.insert(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
.with_children(|parent| {
children.push(
parent
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.)))
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.)))
.id(),
);
children.push(
parent
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.)))
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.)))
.id(),
);
});
@ -166,16 +163,16 @@ mod test {
let mut commands = Commands::new(&mut queue, &world);
let mut children = Vec::new();
commands
.spawn_bundle(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
.with_children(|parent| {
children.push(
parent
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.0)))
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.0)))
.id(),
);
children.push(
parent
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.0)))
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.0)))
.id(),
);
});
@ -208,12 +205,10 @@ mod test {
let parent = {
let mut command_queue = CommandQueue::default();
let mut commands = Commands::new(&mut command_queue, &world);
let parent = commands
.spawn_bundle(Transform::from_xyz(1.0, 0.0, 0.0))
.id();
let parent = commands.spawn(Transform::from_xyz(1.0, 0.0, 0.0)).id();
commands.entity(parent).with_children(|parent| {
children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 2.0, 0.0)).id());
children.push(parent.spawn_bundle(Transform::from_xyz(0.0, 3.0, 0.0)).id());
children.push(parent.spawn(Transform::from_xyz(0.0, 2.0, 0.0)).id());
children.push(parent.spawn(Transform::from_xyz(0.0, 3.0, 0.0)).id());
});
command_queue.apply(&mut world);
schedule.run(&mut world);
@ -287,14 +282,15 @@ mod test {
let mut grandchild = Entity::from_raw(1);
let parent = app
.world
.spawn()
.insert(Transform::from_translation(translation))
.insert(GlobalTransform::IDENTITY)
.spawn((
Transform::from_translation(translation),
GlobalTransform::IDENTITY,
))
.with_children(|builder| {
child = builder
.spawn_bundle(TransformBundle::IDENTITY)
.spawn(TransformBundle::IDENTITY)
.with_children(|builder| {
grandchild = builder.spawn_bundle(TransformBundle::IDENTITY).id();
grandchild = builder.spawn(TransformBundle::IDENTITY).id();
})
.id();
})
@ -327,10 +323,9 @@ mod test {
fn setup_world(world: &mut World) -> (Entity, Entity) {
let mut grandchild = Entity::from_raw(0);
let child = world
.spawn()
.insert(TransformBundle::IDENTITY)
.spawn(TransformBundle::IDENTITY)
.with_children(|builder| {
grandchild = builder.spawn_bundle(TransformBundle::IDENTITY).id();
grandchild = builder.spawn(TransformBundle::IDENTITY).id();
})
.id();
(child, grandchild)
@ -343,8 +338,7 @@ mod test {
assert_eq!(temp_grandchild, grandchild);
app.world
.spawn()
.insert(TransformBundle::IDENTITY)
.spawn(TransformBundle::IDENTITY)
.push_children(&[child]);
std::mem::swap(
&mut *app.world.get_mut::<Parent>(child).unwrap(),

View file

@ -250,7 +250,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
};
projection.update(logical_size.x, logical_size.y);
let default_camera_view = commands
.spawn_bundle(ExtractedView {
.spawn(ExtractedView {
projection: projection.get_projection_matrix(),
transform: GlobalTransform::from_xyz(
0.0,
@ -398,7 +398,7 @@ pub fn prepare_uinodes(
for extracted_uinode in &extracted_uinodes.uinodes {
if current_batch_handle != extracted_uinode.image {
if start != end {
commands.spawn_bundle((UiBatch {
commands.spawn((UiBatch {
range: start..end,
image: current_batch_handle,
z: last_z,
@ -500,11 +500,11 @@ pub fn prepare_uinodes(
// if start != end, there is one last batch to process
if start != end {
commands.spawn_bundle((UiBatch {
commands.spawn(UiBatch {
range: start..end,
image: current_batch_handle,
z: last_z,
},));
});
}
ui_meta.vertices.write_buffer(&render_device, &render_queue);

View file

@ -158,42 +158,42 @@ mod tests {
let mut world = World::default();
let mut queue = CommandQueue::default();
let mut commands = Commands::new(&mut queue, &world);
commands.spawn_bundle(node_with_transform("0"));
commands.spawn(node_with_transform("0"));
commands
.spawn_bundle(node_with_transform("1"))
.spawn(node_with_transform("1"))
.with_children(|parent| {
parent
.spawn_bundle(node_with_transform("1-0"))
.spawn(node_with_transform("1-0"))
.with_children(|parent| {
parent.spawn_bundle(node_with_transform("1-0-0"));
parent.spawn_bundle(node_without_transform("1-0-1"));
parent.spawn_bundle(node_with_transform("1-0-2"));
parent.spawn(node_with_transform("1-0-0"));
parent.spawn(node_without_transform("1-0-1"));
parent.spawn(node_with_transform("1-0-2"));
});
parent.spawn_bundle(node_with_transform("1-1"));
parent.spawn(node_with_transform("1-1"));
parent
.spawn_bundle(node_without_transform("1-2"))
.spawn(node_without_transform("1-2"))
.with_children(|parent| {
parent.spawn_bundle(node_with_transform("1-2-0"));
parent.spawn_bundle(node_with_transform("1-2-1"));
parent.spawn(node_with_transform("1-2-0"));
parent.spawn(node_with_transform("1-2-1"));
parent
.spawn_bundle(node_with_transform("1-2-2"))
.spawn(node_with_transform("1-2-2"))
.with_children(|_| ());
parent.spawn_bundle(node_with_transform("1-2-3"));
parent.spawn(node_with_transform("1-2-3"));
});
parent.spawn_bundle(node_with_transform("1-3"));
parent.spawn(node_with_transform("1-3"));
});
commands
.spawn_bundle(node_without_transform("2"))
.spawn(node_without_transform("2"))
.with_children(|parent| {
parent
.spawn_bundle(node_with_transform("2-0"))
.spawn(node_with_transform("2-0"))
.with_children(|_parent| ());
parent
.spawn_bundle(node_with_transform("2-1"))
.spawn(node_with_transform("2-1"))
.with_children(|parent| {
parent.spawn_bundle(node_with_transform("2-1-0"));
parent.spawn(node_with_transform("2-1-0"));
});
});
queue.apply(&mut world);

View file

@ -23,7 +23,7 @@ struct MyEntity(Entity);
struct Hello;
fn setup(mut commands: Commands) {
let entity = commands.spawn().id();
let entity = commands.spawn_empty().id();
commands.insert_resource(MyEntity(entity));
}

View file

@ -29,10 +29,10 @@ fn setup_cube(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands
.spawn_bundle(TransformBundle::default())
.spawn(TransformBundle::default())
.with_children(|parent| {
// cube
parent.spawn_bundle(PbrBundle {
parent.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
@ -41,7 +41,7 @@ fn setup_cube(
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
@ -56,7 +56,7 @@ fn main() {
```
This code **will not** show a cube on screen.
This is because the entity spawned with `commands.spawn_bundle(…)`
This is because the entity spawned with `commands.spawn(…)`
doesn't have a [`ComputedVisibility`] component.
Since the cube is spawned as a child of an entity without the
[`ComputedVisibility`] component, it will not be visible at all.
@ -76,10 +76,10 @@ fn setup_cube(
// We use SpatialBundle instead of TransformBundle, it contains the
// ComputedVisibility component needed to display the cube,
// In addition to the Transform and GlobalTransform components.
.spawn_bundle(SpatialBundle::default())
.spawn(SpatialBundle::default())
.with_children(|parent| {
// cube
parent.spawn_bundle(PbrBundle {
parent.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
@ -88,7 +88,7 @@ fn setup_cube(
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -14,8 +14,8 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn_bundle(MaterialMesh2dBundle {
commands.spawn(Camera2dBundle::default());
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(Mesh::from(shape::Quad::default())).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(ColorMaterial::from(Color::PURPLE)),

View file

@ -97,7 +97,7 @@ fn star(
star.set_indices(Some(Indices::U32(indices)));
// We can now spawn the entities for the star and the camera
commands.spawn_bundle((
commands.spawn((
// We use a marker component to identify the custom colored meshes
ColoredMesh2d::default(),
// The `Handle<Mesh>` needs to be wrapped in a `Mesh2dHandle` to use 2d rendering instead of 3d
@ -110,7 +110,7 @@ fn star(
));
commands
// And use an orthographic projection
.spawn_bundle(Camera2dBundle::default());
.spawn(Camera2dBundle::default());
}
/// A marker component for colored 2d meshes

View file

@ -36,10 +36,10 @@ fn setup(
let mesh_handle: Mesh2dHandle = meshes.add(mesh).into();
// Spawn camera
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
// Spawn the quad with vertex colors
commands.spawn_bundle(MaterialMesh2dBundle {
commands.spawn(MaterialMesh2dBundle {
mesh: mesh_handle.clone(),
transform: Transform::from_translation(Vec3::new(-96., 0., 0.))
.with_scale(Vec3::splat(128.)),
@ -48,7 +48,7 @@ fn setup(
});
// Spawning the quad with vertex colors and a texture results in tinting
commands.spawn_bundle(MaterialMesh2dBundle {
commands.spawn(MaterialMesh2dBundle {
mesh: mesh_handle,
transform: Transform::from_translation(Vec3::new(96., 0., 0.))
.with_scale(Vec3::splat(128.)),

View file

@ -17,14 +17,15 @@ enum Direction {
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());
commands
.spawn_bundle(SpriteBundle {
commands.spawn(Camera2dBundle::default());
commands.spawn((
SpriteBundle {
texture: asset_server.load("branding/icon.png"),
transform: Transform::from_xyz(100., 0., 0.),
..default()
})
.insert(Direction::Up);
},
Direction::Up,
));
}
/// The sprite is animated by changing its translation depending on the time that has passed since

View file

@ -55,57 +55,62 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let enemy_b_handle = asset_server.load("textures/simplespace/enemy_B.png");
// 2D orthographic camera
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
let horizontal_margin = BOUNDS.x / 4.0;
let vertical_margin = BOUNDS.y / 4.0;
// player controlled ship
commands
.spawn_bundle(SpriteBundle {
commands.spawn((
SpriteBundle {
texture: ship_handle,
..default()
})
.insert(Player {
},
Player {
movement_speed: 500.0, // metres per second
rotation_speed: f32::to_radians(360.0), // degrees per second
});
},
));
// enemy that snaps to face the player spawns on the bottom and left
commands
.spawn_bundle(SpriteBundle {
commands.spawn((
SpriteBundle {
texture: enemy_a_handle.clone(),
transform: Transform::from_xyz(0.0 - horizontal_margin, 0.0, 0.0),
..default()
})
.insert(SnapToPlayer);
commands
.spawn_bundle(SpriteBundle {
},
SnapToPlayer,
));
commands.spawn((
SpriteBundle {
texture: enemy_a_handle,
transform: Transform::from_xyz(0.0, 0.0 - vertical_margin, 0.0),
..default()
})
.insert(SnapToPlayer);
},
SnapToPlayer,
));
// enemy that rotates to face the player enemy spawns on the top and right
commands
.spawn_bundle(SpriteBundle {
commands.spawn((
SpriteBundle {
texture: enemy_b_handle.clone(),
transform: Transform::from_xyz(0.0 + horizontal_margin, 0.0, 0.0),
..default()
})
.insert(RotateToPlayer {
},
RotateToPlayer {
rotation_speed: f32::to_radians(45.0), // degrees per second
});
commands
.spawn_bundle(SpriteBundle {
},
));
commands.spawn((
SpriteBundle {
texture: enemy_b_handle,
transform: Transform::from_xyz(0.0, 0.0 + vertical_margin, 0.0),
..default()
})
.insert(RotateToPlayer {
},
RotateToPlayer {
rotation_speed: f32::to_radians(90.0), // degrees per second
});
},
));
}
/// Demonstrates applying rotation and movement based on keyboard input.

View file

@ -14,10 +14,10 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
// Rectangle
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
sprite: Sprite {
color: Color::rgb(0.25, 0.25, 0.75),
custom_size: Some(Vec2::new(50.0, 100.0)),
@ -27,7 +27,7 @@ fn setup(
});
// Circle
commands.spawn_bundle(MaterialMesh2dBundle {
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::new(50.).into()).into(),
material: materials.add(ColorMaterial::from(Color::PURPLE)),
transform: Transform::from_translation(Vec3::new(-100., 0., 0.)),
@ -35,7 +35,7 @@ fn setup(
});
// Hexagon
commands.spawn_bundle(MaterialMesh2dBundle {
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::RegularPolygon::new(50., 6).into()).into(),
material: materials.add(ColorMaterial::from(Color::TURQUOISE)),
transform: Transform::from_translation(Vec3::new(100., 0., 0.)),

View file

@ -10,8 +10,8 @@ fn main() {
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn_bundle(SpriteBundle {
commands.spawn(Camera2dBundle::default());
commands.spawn(SpriteBundle {
texture: asset_server.load("branding/icon.png"),
..default()
});

View file

@ -10,8 +10,8 @@ fn main() {
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn_bundle(SpriteBundle {
commands.spawn(Camera2dBundle::default());
commands.spawn(SpriteBundle {
texture: asset_server.load("branding/icon.png"),
sprite: Sprite {
// Flip the logo to the left

View file

@ -41,12 +41,13 @@ fn setup(
let texture_handle = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1);
let texture_atlas_handle = texture_atlases.add(texture_atlas);
commands.spawn_bundle(Camera2dBundle::default());
commands
.spawn_bundle(SpriteSheetBundle {
commands.spawn(Camera2dBundle::default());
commands.spawn((
SpriteSheetBundle {
texture_atlas: texture_atlas_handle,
transform: Transform::from_scale(Vec3::splat(6.0)),
..default()
})
.insert(AnimationTimer(Timer::from_seconds(0.1, true)));
},
AnimationTimer(Timer::from_seconds(0.1, true)),
));
}

View file

@ -33,33 +33,36 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
};
let text_alignment = TextAlignment::CENTER;
// 2d camera
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
// Demonstrate changing translation
commands
.spawn_bundle(Text2dBundle {
commands.spawn((
Text2dBundle {
text: Text::from_section("translation", text_style.clone())
.with_alignment(text_alignment),
..default()
})
.insert(AnimateTranslation);
},
AnimateTranslation,
));
// Demonstrate changing rotation
commands
.spawn_bundle(Text2dBundle {
commands.spawn((
Text2dBundle {
text: Text::from_section("rotation", text_style.clone()).with_alignment(text_alignment),
..default()
})
.insert(AnimateRotation);
},
AnimateRotation,
));
// Demonstrate changing scale
commands
.spawn_bundle(Text2dBundle {
commands.spawn((
Text2dBundle {
text: Text::from_section("scale", text_style.clone()).with_alignment(text_alignment),
..default()
})
.insert(AnimateScale);
},
AnimateScale,
));
// Demonstrate text wrapping
let box_size = Vec2::new(300.0, 200.0);
let box_position = Vec2::new(0.0, -250.0);
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
sprite: Sprite {
color: Color::rgb(0.25, 0.25, 0.75),
custom_size: Some(Vec2::new(box_size.x, box_size.y)),
@ -68,7 +71,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
transform: Transform::from_translation(box_position.extend(0.0)),
..default()
});
commands.spawn_bundle(Text2dBundle {
commands.spawn(Text2dBundle {
text: Text::from_section("this text wraps in the box", text_style),
text_2d_bounds: Text2dBounds {
// Wrap text in the rectangle

View file

@ -63,9 +63,9 @@ fn setup(
let atlas_handle = texture_atlases.add(texture_atlas);
// set up a scene to display our texture atlas
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
// draw a sprite from the atlas
commands.spawn_bundle(SpriteSheetBundle {
commands.spawn(SpriteSheetBundle {
transform: Transform {
translation: Vec3::new(150.0, 0.0, 0.0),
scale: Vec3::splat(4.0),
@ -76,7 +76,7 @@ fn setup(
..default()
});
// draw the atlas itself
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
texture: texture_atlas_texture,
transform: Transform::from_xyz(-300.0, 0.0, 0.0),
..default()

View file

@ -11,15 +11,15 @@ fn main() {
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());
commands.spawn(Camera2dBundle::default());
let sprite_handle = asset_server.load("branding/icon.png");
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
texture: sprite_handle.clone(),
..default()
});
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
sprite: Sprite {
// Alpha channel of the color controls transparency.
color: Color::rgba(0.0, 0.0, 1.0, 0.7),
@ -29,7 +29,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
transform: Transform::from_xyz(100.0, 0.0, 0.0),
..default()
});
commands.spawn_bundle(SpriteBundle {
commands.spawn(SpriteBundle {
sprite: Sprite {
color: Color::rgba(0.0, 1.0, 0.0, 0.3),
..default()

View file

@ -16,20 +16,20 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// cube
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
@ -39,7 +39,7 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -24,7 +24,7 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// ground plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 10.0 })),
material: materials.add(StandardMaterial {
base_color: Color::WHITE,
@ -37,7 +37,7 @@ fn setup(
// left wall
let mut transform = Transform::from_xyz(2.5, 2.5, 0.0);
transform.rotate_z(PI / 2.);
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box::new(5.0, 0.15, 5.0))),
transform,
material: materials.add(StandardMaterial {
@ -50,7 +50,7 @@ fn setup(
// back (right) wall
let mut transform = Transform::from_xyz(0.0, 2.5, -2.5);
transform.rotate_x(PI / 2.);
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box::new(5.0, 0.15, 5.0))),
transform,
material: materials.add(StandardMaterial {
@ -62,8 +62,8 @@ fn setup(
});
// cube
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(StandardMaterial {
base_color: Color::PINK,
@ -71,11 +71,12 @@ fn setup(
}),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
})
.insert(Movable);
},
Movable,
));
// sphere
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.5,
..default()
@ -86,8 +87,9 @@ fn setup(
}),
transform: Transform::from_xyz(1.5, 1.0, 1.5),
..default()
})
.insert(Movable);
},
Movable,
));
// ambient light
commands.insert_resource(AmbientLight {
@ -97,7 +99,7 @@ fn setup(
// red point light
commands
.spawn_bundle(PointLightBundle {
.spawn(PointLightBundle {
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
transform: Transform::from_xyz(1.0, 2.0, 0.0),
point_light: PointLight {
@ -109,7 +111,7 @@ fn setup(
..default()
})
.with_children(|builder| {
builder.spawn_bundle(PbrBundle {
builder.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.1,
..default()
@ -125,7 +127,7 @@ fn setup(
// green spot light
commands
.spawn_bundle(SpotLightBundle {
.spawn(SpotLightBundle {
transform: Transform::from_xyz(-1.0, 2.0, 0.0)
.looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z),
spot_light: SpotLight {
@ -139,7 +141,7 @@ fn setup(
..default()
})
.with_children(|builder| {
builder.spawn_bundle(PbrBundle {
builder.spawn(PbrBundle {
transform: Transform::from_rotation(Quat::from_rotation_x(PI / 2.0)),
mesh: meshes.add(Mesh::from(shape::Capsule {
depth: 0.125,
@ -157,7 +159,7 @@ fn setup(
// blue point light
commands
.spawn_bundle(PointLightBundle {
.spawn(PointLightBundle {
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
transform: Transform::from_xyz(0.0, 4.0, 0.0),
point_light: PointLight {
@ -169,7 +171,7 @@ fn setup(
..default()
})
.with_children(|builder| {
builder.spawn_bundle(PbrBundle {
builder.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.1,
..default()
@ -185,7 +187,7 @@ fn setup(
// directional 'sun' light
const HALF_SIZE: f32 = 10.0;
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
// Configure the projection to better fit the scene
shadow_projection: OrthographicProjection {
@ -209,7 +211,7 @@ fn setup(
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<LineMaterial>>,
) {
// Spawn a list of lines with start and end points for each lines
commands.spawn_bundle(MaterialMeshBundle {
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(LineList {
lines: vec![
(Vec3::ZERO, Vec3::new(1.0, 1.0, 0.0)),
@ -42,7 +42,7 @@ fn setup(
});
// Spawn a line strip that goes from point to point
commands.spawn_bundle(MaterialMeshBundle {
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(LineStrip {
points: vec![
Vec3::ZERO,
@ -56,7 +56,7 @@ fn setup(
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -17,12 +17,12 @@ fn main() {
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
..default()
});
const HALF_SIZE: f32 = 1.0;
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
shadow_projection: OrthographicProjection {
left: -HALF_SIZE,
@ -38,7 +38,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
},
..default()
});
commands.spawn_bundle(SceneBundle {
commands.spawn(SceneBundle {
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
..default()
});

View file

@ -27,18 +27,18 @@ fn setup(
info!("Using 4x MSAA");
// cube
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 2.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-3.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -16,7 +16,7 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
projection: OrthographicProjection {
scale: 3.0,
scaling_mode: ScalingMode::FixedVertical(2.0),
@ -28,38 +28,38 @@ fn setup(
});
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// cubes
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(1.5, 0.5, 1.5),
..default()
});
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(1.5, 0.5, -1.5),
..default()
});
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(-1.5, 0.5, 1.5),
..default()
});
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(-1.5, 0.5, -1.5),
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(3.0, 8.0, 5.0),
..default()
});

View file

@ -36,16 +36,18 @@ fn setup(
// parent cube
commands
.spawn_bundle(PbrBundle {
mesh: cube_handle.clone(),
material: cube_material_handle.clone(),
transform: Transform::from_xyz(0.0, 0.0, 1.0),
..default()
})
.insert(Rotator)
.spawn((
PbrBundle {
mesh: cube_handle.clone(),
material: cube_material_handle.clone(),
transform: Transform::from_xyz(0.0, 0.0, 1.0),
..default()
},
Rotator,
))
.with_children(|parent| {
// child cube
parent.spawn_bundle(PbrBundle {
parent.spawn(PbrBundle {
mesh: cube_handle,
material: cube_material_handle,
transform: Transform::from_xyz(0.0, 0.0, 3.0),
@ -53,12 +55,12 @@ fn setup(
});
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 5.0, -4.0),
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(5.0, 10.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -21,7 +21,7 @@ fn setup(
let x01 = (x + 5) as f32 / 10.0;
let y01 = (y + 2) as f32 / 4.0;
// sphere
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.45,
subdivisions: 32,
@ -39,7 +39,7 @@ fn setup(
}
}
// unlit sphere
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.45,
subdivisions: 32,
@ -54,7 +54,7 @@ fn setup(
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(50.0, 50.0, 50.0),
point_light: PointLight {
intensity: 600000.,
@ -64,7 +64,7 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::default(), Vec3::Y),
projection: OrthographicProjection {
scale: 0.01,

View file

@ -76,25 +76,26 @@ fn setup(
let first_pass_layer = RenderLayers::layer(1);
// The cube that will be rendered to the texture.
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: cube_handle,
material: cube_material_handle,
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)),
..default()
})
.insert(FirstPassCube)
.insert(first_pass_layer);
},
FirstPassCube,
first_pass_layer,
));
// Light
// NOTE: Currently lights are shared between passes - see https://github.com/bevyengine/bevy/issues/3462
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)),
..default()
});
commands
.spawn_bundle(Camera3dBundle {
commands.spawn((
Camera3dBundle {
camera_3d: Camera3d {
clear_color: ClearColorConfig::Custom(Color::WHITE),
..default()
@ -108,8 +109,9 @@ fn setup(
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0))
.looking_at(Vec3::ZERO, Vec3::Y),
..default()
})
.insert(first_pass_layer);
},
first_pass_layer,
));
let cube_size = 4.0;
let cube_handle = meshes.add(Mesh::from(shape::Box::new(cube_size, cube_size, cube_size)));
@ -123,18 +125,19 @@ fn setup(
});
// Main pass cube, with material containing the rendered first pass texture.
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: cube_handle,
material: material_handle,
transform: Transform::from_xyz(0.0, 0.0, 1.5)
.with_rotation(Quat::from_rotation_x(-PI / 5.0)),
..default()
})
.insert(MainPassCube);
},
MainPassCube,
));
// The main pass camera.
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -49,7 +49,7 @@ fn setup(
println!("Using DirectionalLight");
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(5.0, 5.0, 0.0),
point_light: PointLight {
intensity: 0.0,
@ -63,7 +63,7 @@ fn setup(
..default()
});
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 100000.0,
shadow_projection: OrthographicProjection {
@ -90,16 +90,17 @@ fn setup(
});
// camera
commands
.spawn_bundle(Camera3dBundle {
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(-1.0, 1.0, 1.0)
.looking_at(Vec3::new(-1.0, 1.0, 0.0), Vec3::Y),
..default()
})
.insert(CameraController::default());
},
CameraController::default(),
));
for z_i32 in -spawn_plane_depth as i32..=0 {
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: sphere_handle.clone(),
material: white_handle.clone(),
transform: Transform::from_xyz(0.0, spawn_height, z_i32 as f32),
@ -108,7 +109,7 @@ fn setup(
}
// ground plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane {
size: 2.0 * spawn_plane_depth,
})),

View file

@ -43,7 +43,7 @@ fn setup(
}));
// sphere - initially a caster
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: sphere_handle.clone(),
material: materials.add(Color::RED.into()),
transform: Transform::from_xyz(-1.0, spawn_height, 0.0),
@ -51,17 +51,18 @@ fn setup(
});
// sphere - initially not a caster
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: sphere_handle,
material: materials.add(Color::BLUE.into()),
transform: Transform::from_xyz(1.0, spawn_height, 0.0),
..default()
})
.insert(NotShadowCaster);
},
NotShadowCaster,
));
// floating plane - initially not a shadow receiver and not a caster
commands.spawn_bundle((
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
material: materials.add(Color::GREEN.into()),
@ -73,7 +74,7 @@ fn setup(
));
// lower ground plane - initially a shadow receiver
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
material: white_handle,
..default()
@ -81,7 +82,7 @@ fn setup(
println!("Using DirectionalLight");
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(5.0, 5.0, 0.0),
point_light: PointLight {
intensity: 0.0,
@ -93,7 +94,7 @@ fn setup(
..default()
});
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 100000.0,
shadow_projection: OrthographicProjection {
@ -118,7 +119,7 @@ fn setup(
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-5.0, 5.0, 5.0)
.looking_at(Vec3::new(-1.0, 1.0, 0.0), Vec3::Y),
..default()

View file

@ -46,8 +46,8 @@ fn setup(
let num_shapes = shapes.len();
for (i, shape) in shapes.into_iter().enumerate() {
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: shape,
material: debug_material.clone(),
transform: Transform::from_xyz(
@ -57,11 +57,12 @@ fn setup(
)
.with_rotation(Quat::from_rotation_x(-PI / 4.)),
..default()
})
.insert(Shape);
},
Shape,
));
}
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 9000.0,
range: 100.,
@ -73,13 +74,13 @@ fn setup(
});
// ground plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane { size: 50. }.into()),
material: materials.add(Color::SILVER.into()),
..default()
});
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 6., 12.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y),
..default()
});

View file

@ -63,7 +63,7 @@ struct Cubemap {
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// directional 'sun' light
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 32000.0,
..default()
@ -75,12 +75,13 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let skybox_handle = asset_server.load(CUBEMAPS[0].0);
// camera
commands
.spawn_bundle(Camera3dBundle {
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
})
.insert(CameraController::default());
},
CameraController::default(),
));
// ambient light
// NOTE: The ambient light is used to scale how bright the environment map is so with a bright
@ -173,7 +174,7 @@ fn asset_loaded(
}
}
if !updated {
commands.spawn_bundle(MaterialMeshBundle::<CubemapMaterial> {
commands.spawn(MaterialMeshBundle::<CubemapMaterial> {
mesh: meshes.add(Mesh::from(shape::Cube { size: 10000.0 })),
material: cubemap_materials.add(CubemapMaterial {
base_color_texture: Some(cubemap.image_handle.clone_weak()),

View file

@ -16,13 +16,13 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(1.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.2, 0.2, 0.2),
@ -49,7 +49,7 @@ fn setup(
// sphere light
commands
.spawn_bundle(PbrBundle {
.spawn(PbrBundle {
mesh: mesh.clone(),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.5, 0.5, 1.0),
@ -61,7 +61,7 @@ fn setup(
..default()
})
.with_children(|children| {
children.spawn_bundle(PointLightBundle {
children.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
radius,

View file

@ -25,19 +25,19 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
commands.spawn_bundle(SceneBundle {
commands.spawn(SceneBundle {
scene: asset_server.load("models/animated/Fox.glb#Scene0"),
..default()
});
// Light
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
transform: Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
directional_light: DirectionalLight {
shadows_enabled: true,
@ -47,16 +47,17 @@ fn setup(
});
// Left Camera
commands
.spawn_bundle(Camera3dBundle {
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(0.0, 200.0, -100.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
})
.insert(LeftCamera);
},
LeftCamera,
));
// Right Camera
commands
.spawn_bundle(Camera3dBundle {
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(100.0, 100., 150.0).looking_at(Vec3::ZERO, Vec3::Y),
camera: Camera {
// Renders the right camera after the left camera, which has a default priority of 0
@ -69,8 +70,9 @@ fn setup(
..default()
},
..default()
})
.insert(RightCamera);
},
RightCamera,
));
}
#[derive(Component)]

View file

@ -28,7 +28,7 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// ground plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
material: materials.add(StandardMaterial {
base_color: Color::GREEN,
@ -44,8 +44,8 @@ fn setup(
let x = rng.gen_range(-5.0..5.0);
let y = rng.gen_range(-5.0..5.0);
let z = rng.gen_range(-5.0..5.0);
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(StandardMaterial {
base_color: Color::BLUE,
@ -53,8 +53,9 @@ fn setup(
}),
transform: Transform::from_xyz(x, y, z),
..default()
})
.insert(Movable);
},
Movable,
));
}
// ambient light
@ -69,7 +70,7 @@ fn setup(
let z = z as f32 - 2.0;
// red spot_light
commands
.spawn_bundle(SpotLightBundle {
.spawn(SpotLightBundle {
transform: Transform::from_xyz(1.0 + x, 2.0, z)
.looking_at(Vec3::new(1.0 + x, 0.0, z), Vec3::X),
spot_light: SpotLight {
@ -83,7 +84,7 @@ fn setup(
..default()
})
.with_children(|builder| {
builder.spawn_bundle(PbrBundle {
builder.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.05,
..default()
@ -95,8 +96,8 @@ fn setup(
}),
..default()
});
builder
.spawn_bundle(PbrBundle {
builder.spawn((
PbrBundle {
transform: Transform::from_translation(Vec3::Z * -0.1),
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.1,
@ -108,14 +109,15 @@ fn setup(
..default()
}),
..default()
})
.insert(NotShadowCaster);
},
NotShadowCaster,
));
});
}
}
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-4.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -56,7 +56,7 @@ fn setup(
});
// textured quad - normal
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: quad_handle.clone(),
material: material_handle,
transform: Transform::from_xyz(0.0, 0.0, 1.5)
@ -64,14 +64,14 @@ fn setup(
..default()
});
// textured quad - modulated
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: quad_handle.clone(),
material: red_material_handle,
transform: Transform::from_rotation(Quat::from_rotation_x(-PI / 5.0)),
..default()
});
// textured quad - modulated
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: quad_handle,
material: blue_material_handle,
transform: Transform::from_xyz(0.0, 0.0, -1.5)
@ -79,7 +79,7 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(3.0, 5.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -19,13 +19,13 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// opaque plane, uses `alpha_mode: Opaque` by default
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 6.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// transparent sphere, uses `alpha_mode: Mask(f32)`
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
@ -45,7 +45,7 @@ fn setup(
..default()
});
// transparent cube, uses `alpha_mode: Blend`
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
// Notice how there is no need to set the `alpha_mode` explicitly here.
// When converting a color to a material using `into()`, the alpha mode is
@ -55,7 +55,7 @@ fn setup(
..default()
});
// opaque sphere
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
@ -65,7 +65,7 @@ fn setup(
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
@ -75,7 +75,7 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -16,20 +16,20 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// cube
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
@ -39,13 +39,13 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(10.0, 10., -5.0).looking_at(Vec3::ZERO, Vec3::Y),
camera_3d: Camera3d {
clear_color: ClearColorConfig::None,

View file

@ -15,30 +15,31 @@ fn main() {
struct MovedScene;
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 5.0, 4.0),
..default()
});
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(1.05, 0.9, 1.5)
.looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
..default()
});
// Spawn the scene as a child of this entity at the given transform
commands.spawn_bundle(SceneBundle {
commands.spawn(SceneBundle {
transform: Transform::from_xyz(0.0, 0.0, -1.0),
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
..default()
});
// Spawn a second scene, and add a tag component to be able to target it later
commands
.spawn_bundle(SceneBundle {
commands.spawn((
SceneBundle {
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
..default()
})
.insert(MovedScene);
},
MovedScene,
));
}
// This system will move all entities that are descendants of MovedScene (which will be all entities spawned in the scene)

View file

@ -16,7 +16,7 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
@ -33,7 +33,7 @@ fn setup(
.collect();
colorful_cube.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
}
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(colorful_cube),
// This is the default color, but note that vertex colors are
// multiplied by the base color, so you'll likely want this to be
@ -43,7 +43,7 @@ fn setup(
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
@ -53,7 +53,7 @@ fn setup(
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -28,28 +28,29 @@ fn setup(
// To draw the wireframe on all entities, set this to 'true'
wireframe_config.global = false;
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// cube
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
})
},
// This enables wireframe drawing on this entity
.insert(Wireframe);
Wireframe,
));
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -25,25 +25,25 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// cube
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
// light
commands.spawn_bundle(PointLightBundle {
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

View file

@ -34,21 +34,21 @@ fn setup(
]));
// Camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(100.0, 100.0, 150.0)
.looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y),
..default()
});
// Plane
commands.spawn_bundle(PbrBundle {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 500000.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// Light
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
transform: Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
directional_light: DirectionalLight {
shadows_enabled: true,
@ -58,7 +58,7 @@ fn setup(
});
// Fox
commands.spawn_bundle(SceneBundle {
commands.spawn(SceneBundle {
scene: asset_server.load("models/animated/Fox.glb#Scene0"),
..default()
});

View file

@ -22,7 +22,7 @@ fn setup(
mut animations: ResMut<Assets<AnimationClip>>,
) {
// Camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
@ -116,7 +116,7 @@ fn setup(
// Create the scene that will be animated
// First entity is the planet
commands
.spawn_bundle((
.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere::default())),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
@ -128,21 +128,23 @@ fn setup(
))
.with_children(|p| {
// This entity is just used for animation, but doesn't display anything
p.spawn_bundle(SpatialBundle::VISIBLE_IDENTITY)
p.spawn((
SpatialBundle::VISIBLE_IDENTITY,
// Add the Name component
.insert(orbit_controller)
.with_children(|p| {
// The satellite, placed at a distance of the planet
p.spawn_bundle((
PbrBundle {
transform: Transform::from_xyz(1.5, 0.0, 0.0),
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()),
..default()
},
// Add the Name component
satellite,
));
});
orbit_controller,
))
.with_children(|p| {
// The satellite, placed at a distance of the planet
p.spawn((
PbrBundle {
transform: Transform::from_xyz(1.5, 0.0, 0.0),
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()),
..default()
},
// Add the Name component
satellite,
));
});
});
}

View file

@ -39,7 +39,7 @@ fn setup(
mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
) {
// Create a camera
commands.spawn_bundle(Camera3dBundle {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
@ -121,13 +121,13 @@ fn setup(
for i in -5..5 {
// Create joint entities
let joint_0 = commands
.spawn_bundle((
.spawn((
Transform::from_xyz(i as f32 * 1.5, 0.0, 0.0),
GlobalTransform::IDENTITY,
))
.id();
let joint_1 = commands
.spawn_bundle((
.spawn((
AnimatedJoint,
Transform::IDENTITY,
GlobalTransform::IDENTITY,
@ -141,8 +141,8 @@ fn setup(
let joint_entities = vec![joint_0, joint_1];
// Create skinned mesh renderer. Note that its transform doesn't affect the position of the mesh.
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: mesh.clone(),
material: materials.add(
Color::rgb(
@ -153,11 +153,12 @@ fn setup(
.into(),
),
..default()
})
.insert(SkinnedMesh {
},
SkinnedMesh {
inverse_bindposes: inverse_bindposes.clone(),
joints: joint_entities,
});
},
));
}
}

Some files were not shown because too many files have changed in this diff Show more