new character format
This commit is contained in:
102
src/character.rs
Normal file
102
src/character.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use crate::{GameState, heads_database::HeadsDatabase, loading_assets::GameAssets};
|
||||
use bevy::{prelude::*, utils::HashMap};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct AnimatedCharacter(pub usize);
|
||||
|
||||
#[derive(Component, Debug, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct CharacterAnimations {
|
||||
pub idle: AnimationNodeIndex,
|
||||
pub run: AnimationNodeIndex,
|
||||
pub jump: AnimationNodeIndex,
|
||||
pub graph: Handle<AnimationGraph>,
|
||||
}
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_systems(
|
||||
Update,
|
||||
(spawn, setup_once_loaded).run_if(in_state(GameState::Playing)),
|
||||
);
|
||||
}
|
||||
|
||||
fn spawn(
|
||||
mut commands: Commands,
|
||||
mut query: Query<(Entity, &AnimatedCharacter), Added<AnimatedCharacter>>,
|
||||
gltf_assets: Res<Assets<Gltf>>,
|
||||
assets: Res<GameAssets>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
) {
|
||||
for (entity, character) in &mut query {
|
||||
let key = heads_db.head_key(character.0);
|
||||
|
||||
let handle = assets
|
||||
.characters
|
||||
.get(format!("{key}.glb").as_str())
|
||||
.unwrap_or_else(|| {
|
||||
//TODO: remove once we use the new format for all
|
||||
info!("Character not found, using default [{}]", key);
|
||||
&assets.characters["angry demonstrator.glb"]
|
||||
});
|
||||
let asset = gltf_assets.get(handle).unwrap();
|
||||
|
||||
commands.entity(entity).insert((
|
||||
Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)),
|
||||
SceneRoot(asset.scenes[0].clone()),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_once_loaded(
|
||||
mut commands: Commands,
|
||||
mut query: Query<(Entity, &mut AnimationPlayer), Added<AnimationPlayer>>,
|
||||
parent_query: Query<&Parent>,
|
||||
animated_character: Query<&AnimatedCharacter>,
|
||||
assets: Res<GameAssets>,
|
||||
gltf_assets: Res<Assets<Gltf>>,
|
||||
mut graphs: ResMut<Assets<AnimationGraph>>,
|
||||
) {
|
||||
for (entity, mut player) in &mut query {
|
||||
let Some(_animated_character) = parent_query
|
||||
.iter_ancestors(entity)
|
||||
.find_map(|ancestor| animated_character.get(ancestor).ok())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let (_, handle) = assets.characters.iter().next().unwrap();
|
||||
let asset = gltf_assets.get(handle).unwrap();
|
||||
|
||||
let animations = asset
|
||||
.named_animations
|
||||
.iter()
|
||||
.map(|(name, animation)| (name.to_string(), animation.clone()))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let (graph, node_indices) = AnimationGraph::from_clips([
|
||||
animations["idle"].clone(),
|
||||
animations["run"].clone(),
|
||||
animations["jump"].clone(),
|
||||
]);
|
||||
|
||||
// // Insert a resource with the current scene information
|
||||
let graph_handle = graphs.add(graph);
|
||||
let animations = CharacterAnimations {
|
||||
idle: node_indices[0],
|
||||
run: node_indices[1],
|
||||
jump: node_indices[2],
|
||||
graph: graph_handle.clone(),
|
||||
};
|
||||
|
||||
let mut transitions = AnimationTransitions::new();
|
||||
transitions
|
||||
.play(&mut player, animations.idle, Duration::ZERO)
|
||||
.repeat();
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(AnimationGraphHandle(animations.graph.clone()))
|
||||
.insert(transitions)
|
||||
.insert(animations);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user