diff --git a/assets/models/alien_naked.glb b/assets/models/alien_naked.glb new file mode 100644 index 0000000..36d3177 Binary files /dev/null and b/assets/models/alien_naked.glb differ diff --git a/src/alien.rs b/src/alien.rs new file mode 100644 index 0000000..7614bae --- /dev/null +++ b/src/alien.rs @@ -0,0 +1,86 @@ +use std::time::Duration; + +use bevy::prelude::*; + +const FOX_PATH: &str = "models/alien_naked.glb"; + +#[derive(Resource)] +struct Animations { + animations: Vec, + graph: Handle, +} + +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, + mut graphs: ResMut>, +) { + // Build the animation graph + let (graph, node_indices) = AnimationGraph::from_clips([ + 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_handle = graphs.add(graph); + commands.insert_resource(Animations { + animations: node_indices, + graph: graph_handle, + }); + + // Fox + commands + .spawn(SceneRoot( + asset_server.load(GltfAssetLabel::Scene(0).from_asset(FOX_PATH)), + )) + .insert(Name::from("Alien")); +} + +fn setup_once_loaded( + mut commands: Commands, + animations: Res, + mut players: Query<(Entity, &mut AnimationPlayer), Added>, +) { + 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, + mut transitions: Query<(&mut AnimationTransitions, &mut AnimationPlayer)>, + keys: Res>, + mut animation_index: Local, +) { + if keys.just_pressed(KeyCode::KeyE) { + 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 + } +} diff --git a/src/main.rs b/src/main.rs index 430aa11..b30fbe4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,8 @@ use bevy::render::view::ColorGrading; use bevy_flycam::prelude::*; use bevy_trenchbroom::prelude::*; +mod alien; + #[derive(SolidClass, Component, Reflect)] #[reflect(Component)] #[geometry(GeometryProvider::new().convex_collider().smooth_by_default_angle().render())] @@ -74,6 +76,8 @@ fn main() { // bevy_flycam setup so we can get a closer look at the scene, mainly for debugging app.add_plugins(PlayerPlugin); + app.add_plugins(alien::plugin); + app.insert_resource(MovementSettings { sensitivity: 0.00005, speed: 12.,