80 lines
2.5 KiB
Rust
80 lines
2.5 KiB
Rust
use bevy::prelude::*;
|
|
use std::time::Duration;
|
|
|
|
pub const ALIEN_ASSET_PATH: &str = "models/alien_naked.glb";
|
|
|
|
#[derive(Resource)]
|
|
pub struct Animations {
|
|
pub animations: Vec<AnimationNodeIndex>,
|
|
pub graph: Handle<AnimationGraph>,
|
|
}
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(Startup, setup);
|
|
app.add_systems(Update, (setup_once_loaded, toggle_animation));
|
|
}
|
|
|
|
fn setup(
|
|
mut commands: Commands,
|
|
asset_server: Res<AssetServer>,
|
|
mut graphs: ResMut<Assets<AnimationGraph>>,
|
|
) {
|
|
// Build the animation graph
|
|
let (graph, node_indices) = AnimationGraph::from_clips([
|
|
asset_server.load(GltfAssetLabel::Animation(2).from_asset(ALIEN_ASSET_PATH)),
|
|
asset_server.load(GltfAssetLabel::Animation(1).from_asset(ALIEN_ASSET_PATH)),
|
|
asset_server.load(GltfAssetLabel::Animation(0).from_asset(ALIEN_ASSET_PATH)),
|
|
]);
|
|
|
|
// Insert a resource with the current scene information
|
|
let graph_handle = graphs.add(graph);
|
|
commands.insert_resource(Animations {
|
|
animations: node_indices,
|
|
graph: graph_handle,
|
|
});
|
|
}
|
|
|
|
fn setup_once_loaded(
|
|
mut commands: Commands,
|
|
animations: Res<Animations>,
|
|
mut players: Query<(Entity, &mut AnimationPlayer), Added<AnimationPlayer>>,
|
|
) {
|
|
for (entity, mut player) in &mut players {
|
|
let mut transitions = AnimationTransitions::new();
|
|
|
|
// Make sure to start the animation via the `AnimationTransitions`
|
|
// component. The `AnimationTransitions` component wants to manage all
|
|
// the animations and will get confused if the animations are started
|
|
// directly via the `AnimationPlayer`.
|
|
transitions
|
|
.play(&mut player, animations.animations[1], Duration::ZERO)
|
|
.repeat();
|
|
|
|
commands
|
|
.entity(entity)
|
|
.insert(AnimationGraphHandle(animations.graph.clone()))
|
|
.insert(transitions);
|
|
}
|
|
}
|
|
|
|
fn toggle_animation(
|
|
animations: Res<Animations>,
|
|
mut transitions: Query<(&mut AnimationTransitions, &mut AnimationPlayer)>,
|
|
keys: Res<ButtonInput<KeyCode>>,
|
|
mut animation_index: Local<u32>,
|
|
) {
|
|
if keys.just_pressed(KeyCode::KeyT) {
|
|
for (mut transition, mut player) in &mut transitions {
|
|
transition
|
|
.play(
|
|
&mut player,
|
|
animations.animations[*animation_index as usize],
|
|
Duration::from_secs(1),
|
|
)
|
|
.repeat();
|
|
}
|
|
|
|
*animation_index ^= 1; // Toggle between 0 and 1
|
|
}
|
|
}
|