Skip to content

Commit 7035806

Browse files
committed
fix: avoid race condition when spawning animated scenes with colliders
1 parent 9e0a263 commit 7035806

1 file changed

Lines changed: 39 additions & 19 deletions

File tree

  • crates/bevy_animation_graph/src/core/animated_scene

crates/bevy_animation_graph/src/core/animated_scene/mod.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,26 +91,30 @@ pub(crate) fn spawn_animated_scenes(
9191
let processed_scene = if animscn.processed_scene.is_some() {
9292
animscn.processed_scene.as_ref().unwrap()
9393
} else {
94-
let Some(scene) = scenes
95-
.get(&animscn.source)
96-
.and_then(|scn| scn.clone_with(&app_type_registry).ok())
97-
else {
98-
continue;
99-
};
94+
if is_scene_ready_to_process(animscn, &scenes, &skeletons, &skeleton_colliders) {
95+
let Some(scene) = scenes
96+
.get(&animscn.source)
97+
.and_then(|scn| scn.clone_with(&app_type_registry).ok())
98+
else {
99+
continue;
100+
};
100101

101-
let scene = process_scene_into_animscn(
102-
scene,
103-
animscn.skeleton.clone(),
104-
animscn.colliders.clone(),
105-
animscn.animation_graph.clone(),
106-
&skeletons,
107-
&skeleton_colliders,
108-
animscn.retargeting.as_ref(),
109-
)
110-
.unwrap();
111-
112-
animscn.processed_scene = Some(scenes.add(scene));
113-
animscn.processed_scene.as_ref().unwrap()
102+
let scene = process_scene_into_animscn(
103+
scene,
104+
animscn.skeleton.clone(),
105+
animscn.colliders.clone(),
106+
animscn.animation_graph.clone(),
107+
&skeletons,
108+
&skeleton_colliders,
109+
animscn.retargeting.as_ref(),
110+
)
111+
.unwrap();
112+
113+
animscn.processed_scene = Some(scenes.add(scene));
114+
animscn.processed_scene.as_ref().unwrap()
115+
} else {
116+
continue;
117+
}
114118
};
115119

116120
commands
@@ -119,6 +123,22 @@ pub(crate) fn spawn_animated_scenes(
119123
}
120124
}
121125

126+
/// Checks whether the scene can be processed
127+
fn is_scene_ready_to_process(
128+
animscn: &AnimatedScene,
129+
scenes: &Assets<Scene>,
130+
skeletons: &Assets<Skeleton>,
131+
skeleton_colliders: &Assets<SkeletonColliders>,
132+
) -> bool {
133+
scenes.contains(&animscn.source)
134+
&& skeletons.contains(&animscn.skeleton)
135+
&& animscn.colliders.as_ref().is_none_or(|c| {
136+
skeleton_colliders
137+
.get(c)
138+
.is_some_and(|c| skeletons.contains(&c.skeleton))
139+
})
140+
}
141+
122142
/// This function finds the [`bevy::animation::AnimationPlayer`] and replaces it with our own.
123143
///
124144
/// It also applies retargeting if necessary.

0 commit comments

Comments
 (0)