Repository navigation
Hierarchy Child Global Transforms are Not Updated When Spawned as a Child #1354
Description
Bevy version
Operating system & version
Pop!_OS ( Ubuntu ) 20.04
What you did
Here is a complete, simple demonstration program. We spawn a parent sprite in the setup system, then in the load_child system, we spawn a child sprite with a (-50, -50) offset translation. We also have the move_parent system, which just moves the parent sprite.
use bevy::prelude::*;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_startup_system(setup.system())
// Comment out the move_parent line below to witness the bugginess 😜
.add_system(move_parent.system())
.add_system(load_child.system())
.run();
}
struct TheParentEnt;
struct Loaded;
fn setup(
commands: &mut Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// Spawn camera
commands.spawn(Camera2dBundle::default());
// Load parent sprite
let texture = asset_server.load("textures/rpg/mobs/boss_bee.png");
// Spawn parent
commands
.spawn(SpriteBundle {
material: materials.add(ColorMaterial::texture(texture)),
..Default::default()
})
.with(TheParentEnt);
}
// Move the parent slowly to the left
fn move_parent(mut query: Query<&mut Transform, With<TheParentEnt>>) {
for mut trans in query.iter_mut() {
trans.translation.x -= 0.1;
}
}
// Load the child sprite
fn load_child(
commands: &mut Commands,
query: Query<Entity, (Without<Loaded>, With<TheParentEnt>)>,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
for ent in query.iter() {
// Spawn the child sprite
let texture = asset_server.load("textures/rpg/chars/hat-guy/hat-guy.png");
commands
.spawn(SpriteBundle {
material: materials.add(ColorMaterial::texture(texture)),
transform: Transform::from_translation(Vec3::new(-50., -50., 0.)),
..Default::default()
})
.with(Parent(ent));
// Prevent processing parent sprite again by marking it loaded
commands.insert_one(ent, Loaded);
}
}What you expected to happen
When running the example below without changes, everything goes as expected, you have the child sprite moving along with the parent, but offset to the left and down from the parent sprite.
When commenting out the move_parent system, the only difference should be that the sprites aren't moving. The child sprite should still be offset to the left and down from the parent sprite.
What actually happened
When you comment out the move_parent system, when the child sprite is spawned, instead of being offset from the parent, it actually ends up in the center of the world.
Additional information
It seems that the GlobalTransform of the child sprite is not updated when it is spawned as a child, until the parent transform is actually changed. Thus, when the move_parent system is active, the child's transform is properly updated, but if the parent doesn't move, then the child's GlobalTransform is never updated and it remains in the center of the universe!
Activity
zicklag commentedon Jan 30, 2021
I verified that it is an update issue by modifying the transform propagation system to always consider a transform component as having "changed" and it fixes the issue. Now I just have to figure out why the added child is not being considdered as a
Changed<Transform>or aChanged<Parent>.Davier commentedon Jan 30, 2021
I think the issue comes from adding the
Parentcomponent directly. The system that automatically adds the correspondingChildrencomponent probably runs after the system that propagates the global transform, and that system relies onChildrenbeing properly set up.When spawning a child entity, try to use the
with_childrenfunction instead ofspawn.tigregalis commentedon Jan 30, 2021
You could do this:
However, I believe the canonical way is:
MinerSebas commentedon Jan 30, 2021
Almost, the problem is, that the two are in the same Stage: See here for further Information #1198
zicklag commentedon Jan 30, 2021
@tigregalis that worked!!! Thanks a lot! I spent all day yesterday wrestling with this, so it's really nice to get it working.
I think I'll go ahead and close this because there is a solution and the weirdness should be worked out with the new hierarchy system comming in: #1198 (comment).
SUPERCILEX commentedon May 9, 2022
@alice-i-cecile This can probably be closed in favor of #1807 or #4197
james7132 commentedon Oct 19, 2022
Is this still an issue? #4197 has been merged. @zicklag if this is still happening and easy to run into despite these changes, please comment, otherwise please close this issue.