diff --git a/Cargo.toml b/Cargo.toml index f7242c21e3a61..f517ee8f22816 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -205,6 +205,10 @@ path = "examples/ecs/ecs_guide.rs" name = "parallel_query" path = "examples/ecs/parallel_query.rs" +[[example]] +name = "hierarchy" +path = "examples/ecs/hierarchy.rs" + [[example]] name = "breakout" path = "examples/game/breakout.rs" diff --git a/examples/ecs/hierarchy.rs b/examples/ecs/hierarchy.rs new file mode 100644 index 0000000000000..43c504f382d4f --- /dev/null +++ b/examples/ecs/hierarchy.rs @@ -0,0 +1,112 @@ +use bevy::prelude::*; + +fn main() { + App::build() + .add_default_plugins() + .add_startup_system(setup.system()) + .add_system(rotate.system()) + .run(); +} + +fn setup( + mut commands: Commands, + asset_server: Res, + mut materials: ResMut>, +) { + commands.spawn(Camera2dComponents::default()); + let texture = asset_server.load("assets/branding/icon.png").unwrap(); + + // Spawn a root entity with no parent + let parent = commands + .spawn(SpriteComponents { + transform: Transform::from_scale(0.75), + material: materials.add(ColorMaterial { + color: Color::WHITE, + texture: Some(texture), + }), + ..Default::default() + }) + // With that entity as a parent, run a lambda that spawns its children + .with_children(|parent| { + // parent is a ChildBuilder, which has a similar API to Commands + parent.spawn(SpriteComponents { + transform: Transform::from_translation(Vec3::new(250.0, 0.0, 0.0)).with_scale(0.75), + material: materials.add(ColorMaterial { + color: Color::BLUE, + texture: Some(texture), + }), + ..Default::default() + }); + }) + // Store parent entity for next sections + .current_entity() + .unwrap(); + + // Another way to create a hierarchy is to add a Parent component to an entity, + // which would be added automatically to parents with other methods. + // Similarly, adding a Parent component will automatically add a Children component to the parent. + commands + .spawn(SpriteComponents { + transform: Transform::from_translation(Vec3::new(-250.0, 0.0, 0.0)).with_scale(0.75), + material: materials.add(ColorMaterial { + color: Color::RED, + texture: Some(texture), + }), + ..Default::default() + }) + // Using the entity from the previous section as the parent: + .with(Parent(parent)); + + // Another way is to use the push_children function to add children after the parent + // entity has already been spawned. + let child = commands + .spawn(SpriteComponents { + transform: Transform::from_translation(Vec3::new(0.0, 250.0, 0.0)).with_scale(0.75), + material: materials.add(ColorMaterial { + color: Color::GREEN, + texture: Some(texture), + }), + ..Default::default() + }) + .current_entity() + .unwrap(); + + // Pushing takes a slice of children to add: + commands.push_children(parent, &[child]); +} + +// A simple system to rotate the root entity, and rotate all its children separately +fn rotate( + mut commands: Commands, + time: Res