Hierarchical (Parent/Child) Entities

Relevant official examples: hierarchy, parenting.

Technically, the Entities/Components themselves cannot form a hierarchy (the ECS is a flat data structure). However, logical hierarchies are a common pattern in games.

Bevy supports creating such a logical link between entities, to form a virtual "hierarchy", by simply adding Parent and Children components on the respective entities.

When using Commands to spawn entities, Commands has methods for adding children to entities, which automatically add the correct components:

// spawn the parent and get its Entity id
let parent = commands.spawn_bundle(MyParentBundle::default())

// do the same for the child
let child = commands.spawn_bundle(MyChildBundle::default())

// add the child to the parent

// you can also use `with_children`:
    .with_children(|parent| {

You can despawn an entire hierarchy with a single command:

fn close_menu(
    mut commands: Commands,
    query: Query<Entity, With<MainMenuUI>>,
) {
    for entity in query.iter() {
        // despawn the entity and its children

Accessing the Parent or Children

To make a system that works with the hierarchy, you typically need two queries:

  • one with the components you need from the child entities
  • one with the components you need from the parent entities

One of the two queries should include the appropriate component, to obtain the entity ids to use with the other one:

  • Parent in the child query, if you want to iterate entities and look up their parents, or
  • Children in the parent query, if you want to iterate entities and look up their children

For example, if we want to get the Transform of cameras (Camera) that have a parent, and the GlobalTransform of their parent:

fn camera_with_parent(
    q_child: Query<(&Parent, &Transform), With<Camera>>,
    q_parent: Query<&GlobalTransform>,
) {
    for (parent, child_transform) in q_child.iter() {
        // `parent` contains the Entity ID we can use
        // to query components from the parent:
        let parent_global_transform = q_parent.get(parent.0);

        // do something with the components

As another example, say we are making a strategy game, and we have Units that are children of a Squad. Say we need to make a system that works on each Squad, and it needs some information about the children:

fn process_squad_damage(
    q_parent: Query<(&MySquadDamage, &Children)>,
    q_child: Query<&MyUnitHealth>,
) {
    // get the properties of each squad
    for (squad_dmg, children) in q_parent.iter() {
        // `children` is a collection of Entity IDs
        for &child in children.iter() {
            // get the health of each child unit
            let health = q_child.get(child);

            // do something

Relative Transforms

If your entities represent "objects in the game world", you probably expect the child to be positioned relative to the parent and move with it.

All Bundles that come with Bevy provide this behavior automatically. You should at least use the basic TransformBundle if you don't need anything else.

For more info, see the dedicated page about transforms.