animate suit

This commit is contained in:
yuni 2024-04-22 23:09:50 +02:00
parent bc9ff6b7a6
commit 44f0770226

View file

@ -11,6 +11,13 @@
use bevy::ecs::system::EntityCommands; use bevy::ecs::system::EntityCommands;
use bevy::prelude::*; use bevy::prelude::*;
pub struct SkeletonPlugin;
impl Plugin for SkeletonPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, animate_skeleton_parts);
}
}
pub fn asset_name_to_path(name: &str) -> &'static str { pub fn asset_name_to_path(name: &str) -> &'static str {
match name { match name {
"suit" => "models/suit_with_collider.glb#Scene0", "suit" => "models/suit_with_collider.glb#Scene0",
@ -105,14 +112,8 @@ pub fn skeleton_name_to_skeletondef(name: &str) -> Option<SkeletonDef> {
} }
} }
pub struct SkeletonPlugin;
impl Plugin for SkeletonPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, animate_skeleton_parts);
}
}
#[derive(Component)] pub struct SkeletonLimb; #[derive(Component)] pub struct SkeletonLimb;
#[derive(Component)] pub struct MirroredLimb;
pub enum SkeletonDef { pub enum SkeletonDef {
Human(HumanDef) Human(HumanDef)
} }
@ -178,6 +179,9 @@ pub fn load(
..default() ..default()
} }
)); ));
if limb.mirror {
parent_limb.insert(MirroredLimb);
}
if !limb.children.is_empty() { if !limb.children.is_empty() {
parent_limb.with_children(|parent| { parent_limb.with_children(|parent| {
for child_limb in limb.children { for child_limb in limb.children {
@ -186,7 +190,7 @@ pub fn load(
} else { } else {
Quat::IDENTITY Quat::IDENTITY
}; };
parent.spawn(( let mut entity_commands = parent.spawn((
child_limb.class, child_limb.class,
SceneBundle { SceneBundle {
scene: load_scene_by_path(child_limb.path.as_str(), asset_server), scene: load_scene_by_path(child_limb.path.as_str(), asset_server),
@ -194,6 +198,9 @@ pub fn load(
..default() ..default()
} }
)); ));
if child_limb.mirror {
entity_commands.insert(MirroredLimb);
}
} }
}); });
} }
@ -233,5 +240,62 @@ pub fn _build_body(
} }
pub fn animate_skeleton_parts( pub fn animate_skeleton_parts(
time: Res<Time>,
mut q_limb: Query<(&mut Transform, &Limb, Option<&MirroredLimb>)>,
) { ) {
let t = time.elapsed_seconds();
for (mut trans, limb, mirror) in &mut q_limb {
let mirror = mirror.is_some();
let m = {|angle| if mirror { 180f32 + angle } else { angle }};
let mut rot = {|x: f32, y: f32, z: f32|
trans.rotation = Quat::from_euler(EulerRot::XYZ,
x.to_radians(), y.to_radians(), z.to_radians())
};
// x: lean head forward/backward
// y: close/open arms together in front of the torso
// z: spread legs sidewards
match limb {
Limb::UpperArmRight => rot(
0.0,
m(40.0 + 5.0 * (t * 0.5).sin()),
20.0 + 10.0 * (t * 0.5).sin(),
),
Limb::UpperArmLeft => rot(
0.0,
m(-(40.0 + 5.0 * (t * 0.5).sin())),
20.0 + 10.0 * (t * 0.5).sin(),
),
Limb::LowerArmRight => rot(
0.0,
m(20.0),
-20.0,
),
Limb::LowerArmLeft => rot(
0.0,
m(-20.0),
-20.0,
),
Limb::UpperLegRight => rot(
-30.0 + 10.0 * (t * 0.5).sin(),
0.0,
-25.0 + 2.5 * (t * 0.5).cos(),
),
Limb::UpperLegLeft => rot(
-30.0 + 10.0 * (t * 0.5).sin(),
0.0,
25.0 - 2.5 * (t * 0.5).cos(),
),
Limb::LowerLegRight => rot(
30.0,
0.0,
0.0,
),
Limb::LowerLegLeft => rot(
30.0,
0.0,
0.0,
),
_ => {},
}
}
} }