diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 4680cce54844d..b0ddd3d7ab4c9 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -130,19 +130,21 @@ async fn load_gltf<'a, 'b>( #[cfg(feature = "bevy_animation")] let paths = { - let mut paths = HashMap::>::new(); + let mut paths = HashMap::)>::new(); for scene in gltf.scenes() { for node in scene.nodes() { - paths_recur(node, &[], &mut paths); + let root_index = node.index(); + paths_recur(node, &[], &mut paths, root_index); } } paths }; #[cfg(feature = "bevy_animation")] - let (animations, named_animations) = { + let (animations, named_animations, animation_roots) = { let mut animations = vec![]; let mut named_animations = HashMap::default(); + let mut animation_roots = HashSet::default(); for animation in gltf.animations() { let mut animation_clip = AnimationClip::default(); for channel in animation.channels() { @@ -189,7 +191,8 @@ async fn load_gltf<'a, 'b>( return Err(GltfError::MissingAnimationSampler(animation.index())); }; - if let Some(path) = paths.get(&node.index()) { + if let Some((root_index, path)) = paths.get(&node.index()) { + animation_roots.insert(root_index); animation_clip.add_curve_to_path( EntityPath { parts: path.clone(), @@ -215,7 +218,7 @@ async fn load_gltf<'a, 'b>( } animations.push(handle); } - (animations, named_animations) + (animations, named_animations, animation_roots) }; let mut meshes = vec![]; @@ -467,10 +470,16 @@ async fn load_gltf<'a, 'b>( } #[cfg(feature = "bevy_animation")] - if !animations.is_empty() { - world - .entity_mut(*node_index_to_entity_map.get(&0).unwrap()) - .insert(AnimationPlayer::default()); + { + // for each node root in a scene, check if it's the root of an animation + // if it is, add the AnimationPlayer component + for node in scene.nodes() { + if animation_roots.contains(&node.index()) { + world + .entity_mut(*node_index_to_entity_map.get(&node.index()).unwrap()) + .insert(AnimationPlayer::default()); + } + } } for (&entity, &skin_index) in &entity_to_skin_index_map { @@ -526,13 +535,18 @@ fn node_name(node: &Node) -> Name { Name::new(name) } -fn paths_recur(node: Node, current_path: &[Name], paths: &mut HashMap>) { +fn paths_recur( + node: Node, + current_path: &[Name], + paths: &mut HashMap)>, + root_index: usize, +) { let mut path = current_path.to_owned(); path.push(node_name(&node)); for child in node.children() { - paths_recur(child, &path, paths); + paths_recur(child, &path, paths, root_index); } - paths.insert(node.index(), path); + paths.insert(node.index(), (root_index, path)); } /// Loads a glTF texture as a bevy [`Image`] and returns it together with its label.