How do I spawn children into an existing component?

1.5k views Asked by At

Assume I have something like this:

use bevy::prelude::*;

// Bevy style tag
struct &CharacterBox;

// Somewhere to store the entity
pub struct Action {
    pub character_box: Option<Entity>,
};

fn setup( mut commands: Commands, mut action: ResMut<Action> ) {
    if let Some(entity) = commands
        .spawn(UiCameraComponents::default())
        .spawn(NodeComponents { /* snip */ })
        .with_children(|p| {
            p.spawn(ButtonComponents { /* snip, snap */ });
        })
        .with(CharacterBox)
        .current_entity()
    {
        action.character_box = Some(entity);
    }
}

A NodeComponents with a button or two from startup...

...and later I want to add more buttons from a system I've added:

fn do_actions(
    mut commands: Commands,
    action: ChangedRes<Action>,
    mut query: Query<(&CharacterBox, &Children)>,
) {

    if let Some(entity) = commands
        .spawn(ButtonComponents { /* ... */ })
        .current_entity()
    {
        let mut charbox = query.get_mut::<Children>(action.character_box.unwrap()).unwrap();
        // I know this is naïve, I know I can't just push in the entity,
        // but it illustrates my point...
        charbox.push(entity); // How do I achieve this?
    }

}

How do insert my spawned entity (component?) into my NodeComponents.Children?

How do I spawn a component into an already existing component?

Or how do I access NodeComponents.Children.ChildBuilder? Can I query ChildBuilders?

Edit: removed edits.

1

There are 1 answers

0
ippi On

Anyway, here is how I solved it:

 let parent_entity = action.character_box.unwrap();
 let new_entity = commands
      .spawn(ButtonComponents { /* ... */ })
      .current_entity()
      .unwrap();

 commands.push_children(parent_entity, &[c]);

(With nested NodeComponents, I had to spawn them seperately, and then push each entity into the other, because to my knowledge there is no way to get the entity from a ChildBuilder, only by using commands.spawn(...).current_entity(). )