Add AnimationGraph::from_clips and simplify animated_fox example (#14853)

# Objective

Add a convenience constructor to make simple animation graphs easier to
build.

I've had some notes about attempting this since #11989 that I just
remembered after seeing #14852.

This partially addresses #14852, but I don't really know animation well
enough to write all of the documentation it's asking for.

## Solution

Add `AnimationGraph::from_clips` and use it to simplify `animated_fox`.

Do some other little bits of incidental cleanup and documentation .

## Testing

I ran `cargo run --example animated_fox`.
This commit is contained in:
Rob Parrett 2024-08-25 07:16:04 -07:00 committed by GitHub
parent 6250698b56
commit 2c3f5a00ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 20 deletions

View file

@ -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<AnimationNodeIndex>)
where
I: IntoIterator<Item = Handle<AnimationClip>>,
<I as 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.
///

View file

@ -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 {

View file

@ -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<Assets<AnimationGraph>>,
) {
// 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<Animations>,