@@ -20,6 +20,21 @@ pub fn sync_simple_transforms(
20
20
* global_transform = GlobalTransform :: from ( * transform) ;
21
21
} ) ;
22
22
}
23
+ /// Update [`GlobalTransform`] component of entities that aren't in the hierarchy
24
+ /// and lost their parent last frame.
25
+ ///
26
+ /// Third party plugins should use [`transform_propagate_system_set`](crate::transform_propagate_system_set)
27
+ /// to propagate transforms correctly.
28
+ pub fn sync_simple_transforms_orphaned (
29
+ mut query : Query < ( & Transform , & mut GlobalTransform ) , Without < Children > > ,
30
+ changed : Query < ( ) , Changed < Transform > > ,
31
+ orphaned : RemovedComponents < Parent > ,
32
+ ) {
33
+ let mut iter = query. iter_many_mut ( orphaned. iter ( ) . filter ( |e| !changed. contains ( * e) ) ) ;
34
+ while let Some ( ( transform, mut global_transform) ) = iter. fetch_next ( ) {
35
+ * global_transform = GlobalTransform :: from ( * transform) ;
36
+ }
37
+ }
23
38
24
39
/// Update [`GlobalTransform`] component of entities based on entity hierarchy and
25
40
/// [`Transform`] component.
@@ -181,6 +196,10 @@ mod test {
181
196
fn correct_parent_removed ( ) {
182
197
ComputeTaskPool :: init ( TaskPool :: default) ;
183
198
let mut world = World :: default ( ) ;
199
+ let offset_global_transform =
200
+ |offset| GlobalTransform :: from ( Transform :: from_xyz ( offset, offset, offset) ) ;
201
+ let offset_transform =
202
+ |offset| TransformBundle :: from_transform ( Transform :: from_xyz ( offset, offset, offset) ) ;
184
203
185
204
let mut update_stage = SystemStage :: parallel ( ) ;
186
205
update_stage. add_system_set ( transform_propagate_system_set ( ) ) ;
@@ -190,13 +209,9 @@ mod test {
190
209
191
210
let mut command_queue = CommandQueue :: default ( ) ;
192
211
let mut commands = Commands :: new ( & mut command_queue, & world) ;
193
- let root = commands
194
- . spawn ( TransformBundle :: from_transform ( Transform :: from_xyz (
195
- 9.9 , 9.9 , 9.9 ,
196
- ) ) )
197
- . id ( ) ;
198
- let parent = commands. spawn ( TransformBundle :: IDENTITY ) . id ( ) ;
199
- let child = commands. spawn ( TransformBundle :: IDENTITY ) . id ( ) ;
212
+ let root = commands. spawn ( offset_transform ( 3.3 ) ) . id ( ) ;
213
+ let parent = commands. spawn ( offset_transform ( 4.4 ) ) . id ( ) ;
214
+ let child = commands. spawn ( offset_transform ( 5.5 ) ) . id ( ) ;
200
215
commands. entity ( parent) . set_parent ( root) ;
201
216
commands. entity ( child) . set_parent ( parent) ;
202
217
command_queue. apply ( & mut world) ;
@@ -216,7 +231,19 @@ mod test {
216
231
217
232
assert_eq ! (
218
233
world. get:: <GlobalTransform >( parent) . unwrap( ) ,
219
- & GlobalTransform :: from( Transform :: IDENTITY )
234
+ & offset_global_transform( 4.4 )
235
+ ) ;
236
+
237
+ // Remove parent of `child`
238
+ let mut command_queue = CommandQueue :: default ( ) ;
239
+ let mut commands = Commands :: new ( & mut command_queue, & world) ;
240
+ commands. entity ( child) . remove_parent ( ) ;
241
+ command_queue. apply ( & mut world) ;
242
+ schedule. run ( & mut world) ;
243
+
244
+ assert_eq ! (
245
+ world. get:: <GlobalTransform >( child) . unwrap( ) ,
246
+ & offset_global_transform( 5.5 )
220
247
) ;
221
248
}
222
249
0 commit comments