bevyengine / bevyengine/bevy

child spawned before a parent sometimes becomes a sibling?

Open
#9,888 0 comments 0 reactions 0 assignees View on GitHub
A-UI C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

main 1116207

Replicates in 0.11.2

## What you did

```
use bevy::prelude::*;

const S: Val = Val::Px(100.);
const B: Val = Val::Px(10.);

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}

fn update(input: Res>, mut root_node_query: Query<&mut Style, Without>, mut text_query: Query<&mut Text>) {
if input.just_pressed(KeyCode::W) {
for mut style in root_node_query.iter_mut() {
style.width = match style.width {
Val::Auto => Val::Percent(100.),
_ => Val::Auto,
};
text_query.single_mut().sections[1].value = format!("{:?}", style.width);
}
}

if input.just_pressed(KeyCode::Space) {
for mut style in root_node_query.iter_mut() {
style.align_items = match style.align_items {
AlignItems::Default => AlignItems::Start,
AlignItems::Start => AlignItems::Stretch,
AlignItems::Stretch => AlignItems::Baseline,
AlignItems::Baseline => AlignItems::Center,
AlignItems::Center => AlignItems::End,
AlignItems::End => AlignItems::FlexStart,
AlignItems::FlexStart => AlignItems::FlexEnd,
AlignItems::FlexEnd => AlignItems::Default,
};
text_query.single_mut().sections[3].value = format!("{:?}", style.align_items);
}
}
}

fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands
.spawn(NodeBundle {
style: Style {
flex_direction: FlexDirection::Column,
row_gap: B,
..Default::default()
},
..Default::default()
})
.with_children(|builder| {
spawn_grid(builder);

builder.spawn(TextBundle::from_sections([
"width: ".into(),
"Auto".into(),
"\nalign_items: ".into(),
"Default".into(),
]));
});
}

fn spawn_grid(builder: &mut ChildBuilder) {
builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_1(builder);
case_1(builder);
});

builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_2(builder);
case_1(builder);
});

builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_3(builder);
case_1(builder);
});
}

fn child() -> NodeBundle {
NodeBundle {
style: Style {
flex_grow: 1.,
..Default::default()
},
background_color: Color::BLUE.into(),
..Default::default()
}
}

fn parent() -> NodeBundle {
NodeBundle {
style: Style {
width: S,
height: S,
border: UiRect::all(B),
..Default::default()
},
background_color: Color::RED.into(),
..Default::default()
}
}

fn child_2() -> NodeBundle {
NodeBundle {
style: Style {
..Default::default()
},
background_color: Color::BLUE.into(),
..Default::default()
}
}

fn parent_2() -> NodeBundle {
NodeBundle {
style: Style {
width: S,
height: S,
border: UiRect::all(B),
align_items: AlignItems::Stretch,
..Default::default()
},
background_color: Color::RED.into(),
..Default::default()
}
}

fn case_1(builder: &mut ChildBuilder) {
builder.spawn(parent()).with_children(|builder| {
builder.spawn(child());
});
}

fn case_2(builder: &mut ChildBuilder) {
let parent_id = builder.spawn(parent()).id();
let child_id = builder.spawn(child()).id();
builder.add_command(AddChild {
parent: parent_id,
child: child_id,
});
}

fn case_3(builder: &mut ChildBuilder) {
let child_id = builder.spawn(child_2()).id();
builder.spawn(parent_2()).add_child(child_id);
}
```

## What went wrong

Lots of bugs, as far as I can tell:

layout_bug_auto_default

1. Should not have a black gap on the end.
2. Second node should have a blue child node centered on it and the gap between the second and third node is doubled.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.

layout_bug_auto_start

1. This row is correct.
2. Second node should have a blue child node centered on it and the gap between the second and third node is doubled.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.

layout_bug_percent_default

1. This row is correct.
2. The blue child is added as a child of its parent's parent.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.

Other combinations also have problems, not got time to write them all up now.

Contributor guide

Open the contributing guide

Research direction

Run the provided Rust reproduction and start with the setup, spawn_grid, case_2, and case_3 entry points, comparing the different child-attachment paths. Done means the reproduced layouts consistently retain the intended parent-child relationships, child positioning, and gap sizes across the listed width and align_items states.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.