Skip to content

Commit

Permalink
Also fix for entities without children
Browse files Browse the repository at this point in the history
  • Loading branch information
nicopap committed Jan 18, 2023
1 parent e879db3 commit 9fbed50
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
9 changes: 9 additions & 0 deletions crates/bevy_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub enum TransformSystem {
pub fn transform_propagate_system_set() -> SystemSet {
SystemSet::new()
.with_system(systems::sync_simple_transforms)
.with_system(systems::sync_simple_transforms_orphaned)
.with_system(systems::propagate_transforms)
}

Expand All @@ -103,6 +104,10 @@ impl Plugin for TransformPlugin {
StartupStage::PostStartup,
systems::sync_simple_transforms.label(TransformSystem::TransformPropagate),
)
.add_startup_system_to_stage(
StartupStage::PostStartup,
systems::sync_simple_transforms_orphaned.label(TransformSystem::TransformPropagate),
)
.add_startup_system_to_stage(
StartupStage::PostStartup,
systems::propagate_transforms.label(TransformSystem::TransformPropagate),
Expand All @@ -111,6 +116,10 @@ impl Plugin for TransformPlugin {
CoreStage::PostUpdate,
systems::sync_simple_transforms.label(TransformSystem::TransformPropagate),
)
.add_system_to_stage(
CoreStage::PostUpdate,
systems::sync_simple_transforms_orphaned.label(TransformSystem::TransformPropagate),
)
.add_system_to_stage(
CoreStage::PostUpdate,
systems::propagate_transforms.label(TransformSystem::TransformPropagate),
Expand Down
43 changes: 35 additions & 8 deletions crates/bevy_transform/src/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ pub fn sync_simple_transforms(
*global_transform = GlobalTransform::from(*transform);
});
}
/// Update [`GlobalTransform`] component of entities that aren't in the hierarchy
/// and lost their parent last frame.
///
/// Third party plugins should use [`transform_propagate_system_set`](crate::transform_propagate_system_set)
/// to propagate transforms correctly.
pub fn sync_simple_transforms_orphaned(
mut query: Query<(&Transform, &mut GlobalTransform), Without<Children>>,
changed: Query<(), Changed<Transform>>,
orphaned: RemovedComponents<Parent>,
) {
let mut iter = query.iter_many_mut(orphaned.iter().filter(|e| !changed.contains(*e)));
while let Some((transform, mut global_transform)) = iter.fetch_next() {
*global_transform = GlobalTransform::from(*transform);
}
}

/// Update [`GlobalTransform`] component of entities based on entity hierarchy and
/// [`Transform`] component.
Expand Down Expand Up @@ -181,6 +196,10 @@ mod test {
fn correct_parent_removed() {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::default();
let offset_global_transform =
|offset| GlobalTransform::from(Transform::from_xyz(offset, offset, offset));
let offset_transform =
|offset| TransformBundle::from_transform(Transform::from_xyz(offset, offset, offset));

let mut update_stage = SystemStage::parallel();
update_stage.add_system_set(transform_propagate_system_set());
Expand All @@ -190,13 +209,9 @@ mod test {

let mut command_queue = CommandQueue::default();
let mut commands = Commands::new(&mut command_queue, &world);
let root = commands
.spawn(TransformBundle::from_transform(Transform::from_xyz(
9.9, 9.9, 9.9,
)))
.id();
let parent = commands.spawn(TransformBundle::IDENTITY).id();
let child = commands.spawn(TransformBundle::IDENTITY).id();
let root = commands.spawn(offset_transform(3.3)).id();
let parent = commands.spawn(offset_transform(4.4)).id();
let child = commands.spawn(offset_transform(5.5)).id();
commands.entity(parent).set_parent(root);
commands.entity(child).set_parent(parent);
command_queue.apply(&mut world);
Expand All @@ -216,7 +231,19 @@ mod test {

assert_eq!(
world.get::<GlobalTransform>(parent).unwrap(),
&GlobalTransform::from(Transform::IDENTITY)
&offset_global_transform(4.4)
);

// Remove parent of `child`
let mut command_queue = CommandQueue::default();
let mut commands = Commands::new(&mut command_queue, &world);
commands.entity(child).remove_parent();
command_queue.apply(&mut world);
schedule.run(&mut world);

assert_eq!(
world.get::<GlobalTransform>(child).unwrap(),
&offset_global_transform(5.5)
);
}

Expand Down

0 comments on commit 9fbed50

Please sign in to comment.