bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Transform not propagated for child due to delay of inserting `Children`

Open jakobhellermann opened this issue 4 years ago • 2 comments

In the following code snippet, the 1.5 scale is not applied to the scene:

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut scene_spawner: ResMut<SceneSpawner>,
) {
    let scene_holder = commands
        .spawn()
        .insert(GlobalTransform::default())
        .insert(Transform::from_scale(Vec3::splat(1.5)))
        .insert(Holder)
        .id();

    let scene_handle = asset_server.load("models/AlienCake/cakeBirthday.glb#Scene0");
    scene_spawner.spawn_as_child(scene_handle, scene_holder);
}

The transform_propagate_system only runs if either the parent is Changed or the child is Changed. However, in this case the order of operations is

  1. scene_holder 0v0 is spawned (and is Changed for one frame)
  2. later the scene is spawned (e.g. 0v3) 0v3 is Changed for one frame. A Parent(0v0) component is scheduled to be added via commands.
  3. parent_update_system is run, but the insert Children command is not yet processed
  4. transform_propagate_system is run. 0v3 is still Changed, but since 0v0 has no children yet nothing happens.
  5. Next frame. 0v0 now has Children([0v3]).
  6. parent_update_system is run, nothing to be done
  7. transform_propagate_system is run. This time there are children for 0v0, but 0v3 is not changed anymore, so nothing happens.

The problem is "fixed" by either adding a

fn force_transform_change(mut q: Query<&mut Transform>) {
    for mut t in q.iter_mut() { t.deref_mut(); }
}

or removing the Changed from transform_propagate_system.

It is also fixed by adding .with_children(|_| {}) to the scene_holder, because then the parent_update_system can simply insert to the existing children which works without delay.

A simpler repro is here.

jakobhellermann avatar Apr 03 '21 10:04 jakobhellermann

The repro can be fixed by using commands.entity(parent).push_children(&[child]) instead of .insert(Parent(parent)).

jakobhellermann avatar Apr 03 '21 10:04 jakobhellermann

Is this still an issue after #4197?

james7132 avatar Nov 12 '22 16:11 james7132

I can confirm this is fixed with #4197, using the repro linked earlier.

nicopap avatar Jan 31 '23 09:01 nicopap