Skip to content

Commit 336583a

Browse files
committed
Update EntityMut's location in push_children() and insert_children() (#2604)
## Objective This code would result in a crash: ```rust use bevy::prelude::*; fn main() { let mut world = World::new(); let child = world.spawn().id(); world.spawn().push_children(&[child]); } ``` ## Solution Update the `EntityMut`'s location after inserting a component on the children entities, as it may have changed.
1 parent 90586a4 commit 336583a

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

crates/bevy_transform/src/hierarchy/child_builder.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,16 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {
219219
fn push_children(&mut self, children: &[Entity]) -> &mut Self {
220220
let parent = self.id();
221221
{
222-
// SAFE: parent entity is not modified
222+
// SAFE: parent entity is not modified and its location is updated manually
223223
let world = unsafe { self.world_mut() };
224224
for child in children.iter() {
225225
world
226226
.entity_mut(*child)
227227
// FIXME: don't erase the previous parent (see #1545)
228228
.insert_bundle((Parent(parent), PreviousParent(parent)));
229229
}
230+
// Inserting a bundle in the children entities may change the parent entity's location if they were of the same archetype
231+
self.update_location();
230232
}
231233
if let Some(mut children_component) = self.get_mut::<Children>() {
232234
children_component.0.extend(children.iter().cloned());
@@ -239,14 +241,16 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {
239241
fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
240242
let parent = self.id();
241243
{
242-
// SAFE: parent entity is not modified
244+
// SAFE: parent entity is not modified and its location is updated manually
243245
let world = unsafe { self.world_mut() };
244246
for child in children.iter() {
245247
world
246248
.entity_mut(*child)
247249
// FIXME: don't erase the previous parent (see #1545)
248250
.insert_bundle((Parent(parent), PreviousParent(parent)));
249251
}
252+
// Inserting a bundle in the children entities may change the parent entity's location if they were of the same archetype
253+
self.update_location();
250254
}
251255

252256
if let Some(mut children_component) = self.get_mut::<Children>() {
@@ -471,4 +475,11 @@ mod tests {
471475
PreviousParent(parent)
472476
);
473477
}
478+
479+
#[test]
480+
fn regression_push_children_same_archetype() {
481+
let mut world = World::new();
482+
let child = world.spawn().id();
483+
world.spawn().push_children(&[child]);
484+
}
474485
}

0 commit comments

Comments
 (0)