bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Allow multiple `children!` in one bundle

Open molikto opened this issue 6 months ago • 4 comments

What problem does this solve or what need does it fill?

commands.spawn((
     children![],
     children![],
 ));

currently crash with has duplicate components: bevy_ecs::hierarchy::Children

What solution would you like?

Allow multiple bevy_ecs::hierarchy::Children and merge them.

maybe some component can have a "merge strategy" instead of panic.

or maybe it will be solved as part of bsn?

What alternative(s) have you considered?

Additional context

I want to have this:

pub fn children_opt<T: Bundle>(opt: Option<T>) -> impl Bundle {
    Children::spawn(
        SpawnIter(opt.into_iter())
    )
}
pub fn two_opt_children_bundle(
) -> impl Bundle {
    (
        children_opt(Some(Name::new("c1"))),
        children_opt(Some(Name::new("c2")))
    )
}

Also if we can do this then it gives an alternative solution to https://github.com/bevyengine/bevy/issues/18953, you can have the cfg outside one children! marco, and have another one.

molikto avatar May 27 '25 08:05 molikto

Does something like this not satisfy your use-case?

fn setup(mut commands: Commands) {
    commands.spawn((Name::new("parent"), optional_children()));
}

fn optional_children() -> impl Bundle {
    Children::spawn(SpawnIter(
        [Some(Name::new("a")), None, Some(Name::new("b"))]
            .into_iter()
            .flatten(),
    ))
}

rparrett avatar May 27 '25 13:05 rparrett

Does something like this not satisfy your use-case?

fn setup(mut commands: Commands) { commands.spawn((Name::new("parent"), optional_children())); }

fn optional_children() -> impl Bundle { Children::spawn(SpawnIter( [Some(Name::new("a")), None, Some(Name::new("b"))] .into_iter() .flatten(), )) }

doesn't work when you have Some(Transform::IDENTITY), None, Some(Name::new("b")). Also even if it works, it is still beneficial to be able to write children! twice. (for modularity purposes)

molikto avatar May 27 '25 13:05 molikto

I think it wouldn't be children! that needs to be changed, but having multiple hierarchy::Children components. children! is just a small convenience macro for that.

How are we supposed to tell the ECS system that we need to merge those components? Is there any similar mechanic by that already existing?

Unless you want to have a similar macros that could eventually go like that:

children_mul![
  [
    children_opt
  ],
  [
    two_opt_children_bundle
  ]
]

ForwardFeed avatar May 27 '25 16:05 ForwardFeed

I think it wouldn't be children! that needs to be changed, but having multiple hierarchy::Children components.

Agreed. I really don't see a way around this.

alice-i-cecile avatar Jun 02 '25 18:06 alice-i-cecile

#19491 will help with this

You will then have

fn setup(mut commands: Commands) {
    commands.spawn((Name::new("parent"), optional_children()));
}

fn optional_children() -> impl Bundle {
    Children::spawn(SpawnIter(
        [(Some(Name::new("a")), None), (None, None), (Some(Name::new("b")), Some(Transform::IDENTITY)]
            .into_iter(),
    ))
}

hukasu avatar Jun 15 '25 15:06 hukasu

Merging discussion into #19715.

alice-i-cecile avatar Jun 19 '25 17:06 alice-i-cecile

Merging discussion into #19715.

Not sure they are exactly duplicate. What I want is allow multiple children in a Bundle by perform merging bundle content at insertion time. It is currently blocked by the bundle check that disallow duplicate components in a bundle.

https://github.com/bevyengine/bevy/issues/19715 is more about automatical insertion of the reverse relation with children! marco. I have no opinion on this.

molikto avatar Jun 19 '25 23:06 molikto