forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add hierarchy example (bevyengine#565)
add ecs/hierarchy example
- Loading branch information
Showing
2 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<AssetServer>, | ||
mut materials: ResMut<Assets<ColorMaterial>>, | ||
) { | ||
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<Time>, | ||
mut parents_query: Query<(Entity, &mut Transform, &mut Children, &Sprite)>, | ||
children_query: Query<(&mut Transform, &Sprite)>, | ||
) { | ||
let angle = std::f32::consts::PI / 2.0; | ||
for (parent, mut transform, mut children, _) in &mut parents_query.iter() { | ||
transform.rotate(Quat::from_rotation_z(-angle * time.delta_seconds)); | ||
|
||
// To iterate through the entities children, just treat the Children component as a Vec | ||
// Alternatively, you could query entities that have a Parent component | ||
for child in children.iter() { | ||
let mut transform = children_query.get_mut::<Transform>(*child).unwrap(); | ||
transform.rotate(Quat::from_rotation_z(angle * 2.0 * time.delta_seconds)); | ||
} | ||
|
||
// To demonstrate removing children, we'll start to remove the children after a couple of seconds | ||
if time.seconds_since_startup >= 2.0 && children.len() == 3 { | ||
// Using .despawn() on an entity does not remove it from its parent's list of children! | ||
// It must be done manually if using .despawn() | ||
// NOTE: This is a bug. Eventually Bevy will update the children list automatically | ||
let child = children.pop().unwrap(); | ||
commands.despawn(child); | ||
} | ||
|
||
if time.seconds_since_startup >= 4.0 { | ||
// Alternatively, you can use .despawn_recursive() | ||
// This will remove the entity from its parent's list of children, as well as despawn | ||
// any children the entity has. | ||
commands.despawn_recursive(parent); | ||
} | ||
} | ||
} |