diff --git a/crates/bevy_animation/src/graph.rs b/crates/bevy_animation/src/graph.rs index 3f065b7911..aeeed9fcdf 100644 --- a/crates/bevy_animation/src/graph.rs +++ b/crates/bevy_animation/src/graph.rs @@ -192,6 +192,23 @@ impl AnimationGraph { (graph, node_index) } + /// A convenience method to create an [`AnimationGraph`]s with an iterator + /// of clips. + /// + /// All of the animation clips will be direct children of the root with + /// weight 1.0. + /// + /// Returns the the graph and indices of the new nodes. + pub fn from_clips<'a, I>(clips: I) -> (Self, Vec) + where + I: IntoIterator>, + ::IntoIter: 'a, + { + let mut graph = Self::new(); + let indices = graph.add_clips(clips, 1.0, graph.root).collect(); + (graph, indices) + } + /// Adds an [`AnimationClip`] to the animation graph with the given weight /// and returns its index. /// diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index 70c49b3c39..bf2904440c 100755 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -529,7 +529,10 @@ impl ActiveAnimation { } } -/// Animation controls +/// Animation controls. +/// +/// Automatically added to any root animations of a `SceneBundle` when it is +/// spawned. #[derive(Component, Default, Reflect)] #[reflect(Component)] pub struct AnimationPlayer { diff --git a/examples/animation/animated_fox.rs b/examples/animation/animated_fox.rs index da90484f7b..a167e2b171 100644 --- a/examples/animation/animated_fox.rs +++ b/examples/animation/animated_fox.rs @@ -9,6 +9,8 @@ use bevy::{ prelude::*, }; +const FOX_PATH: &str = "models/animated/Fox.glb"; + fn main() { App::new() .insert_resource(AmbientLight { @@ -37,26 +39,17 @@ fn setup( mut graphs: ResMut>, ) { // Build the animation graph - let mut graph = AnimationGraph::new(); - let animations = graph - .add_clips( - [ - GltfAssetLabel::Animation(2).from_asset("models/animated/Fox.glb"), - GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"), - GltfAssetLabel::Animation(0).from_asset("models/animated/Fox.glb"), - ] - .into_iter() - .map(|path| asset_server.load(path)), - 1.0, - graph.root, - ) - .collect(); + let (graph, node_indices) = AnimationGraph::from_clips([ + asset_server.load(GltfAssetLabel::Animation(2).from_asset(FOX_PATH)), + asset_server.load(GltfAssetLabel::Animation(1).from_asset(FOX_PATH)), + asset_server.load(GltfAssetLabel::Animation(0).from_asset(FOX_PATH)), + ]); // Insert a resource with the current scene information - let graph = graphs.add(graph); + let graph_handle = graphs.add(graph); commands.insert_resource(Animations { - animations, - graph: graph.clone(), + animations: node_indices, + graph: graph_handle, }); // Camera @@ -91,7 +84,7 @@ fn setup( // Fox commands.spawn(SceneBundle { - scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")), + scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset(FOX_PATH)), ..default() }); @@ -104,7 +97,8 @@ fn setup( println!(" - return: change animation"); } -// Once the scene is loaded, start the animation +// An `AnimationPlayer` is automatically added to the scene when it's ready. +// When the player is added, start the animation. fn setup_scene_once_loaded( mut commands: Commands, animations: Res,