You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a model named Feminine_TPose.gltf,and animationClip was saved in Feminine_TPose.gltf;
Now I want to load Feminine_TPose.gltf as entity Player, animations loaded from Feminine_TPose.gltf, then bind animations to Player then play;
I don't now how to do this, below is my code from example:
`
//! Plays animations from a skinned glTF.
use std::{f32::consts::PI, sync::atomic::AtomicBool, time::Duration};
use bevy::{animation::RepeatAnimation, pbr::CascadeShadowConfigBuilder, prelude::*};
const GLTF_PATH: &str = "models/animated/Feminine_TPose.gltf";
const ANIM_PATH: &str = "models/animated/F_Dances_001.gltf";
static ACTIVE: AtomicBool = AtomicBool::new(true);
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, check_load_assets)
// .add_systems(Update, keyboard_control)
.run();
}
#[derive(Resource)]
struct Animations {
animations: Vec<AnimationNodeIndex>,
graph_handle: Handle<AnimationGraph>,
}
#[derive(Resource)]
struct AnimationResources {
character_model: Handle<Gltf>,
animation_model: Handle<Gltf>,
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let anim = asset_server.load(ANIM_PATH);
// Build the animation graph
// 加载模型和动画
let model = asset_server.load(GLTF_PATH);
//保存资源以便后续使用
commands.insert_resource(AnimationResources {
character_model: model,
animation_model: anim,
});
// Camera
commands.spawn((
Camera3d::default(),
Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y),
));
// Plane
commands.spawn((
Mesh3d(meshes.add(Plane3d::default().mesh().size(500000.0, 500000.0))),
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
));
// Light
commands.spawn((
Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
DirectionalLight {
shadows_enabled: true,
..default()
},
CascadeShadowConfigBuilder {
first_cascade_far_bound: 200.0,
maximum_distance: 400.0,
..default()
}
.build(),
));
// Instructions
commands.spawn((
Text::new(concat!(
"space: play / pause\n",
"up / down: playback speed\n",
"left / right: seek\n",
"1-3: play N times\n",
"L: loop forever\n",
"return: change animation\n",
)),
Node {
position_type: PositionType::Absolute,
top: Val::Px(12.0),
left: Val::Px(12.0),
..default()
},
));
}
// An `AnimationPlayer` is automatically added to the scene when it's ready.
// When the player is added, start the animation.
fn check_load_assets(
mut commands: Commands,
mut gltf_assets: ResMut<Assets<Gltf>>,
mut scenes: ResMut<Assets<Scene>>,
asset_server: Res<AssetServer>,
mut graphs: ResMut<Assets<AnimationGraph>>,
animation_resources: Res<AnimationResources>,
) {
if !ACTIVE.load(std::sync::atomic::Ordering::SeqCst){
// commands.run_system_cached(setup_scene_once_loaded);
commands.run_system_cached(keyboard_control);
return;
}
//
if !asset_server.is_loaded(animation_resources.animation_model.id()){
return;
}
if !asset_server.is_loaded(animation_resources.character_model.id()){
return;
}
info!("all assets load complete");
let (animations, named_animations) = match gltf_assets.get(animation_resources.animation_model.id()){
Some(res) => (res.animations.clone(), res.named_animations.clone()),
_ => return,
};
let model = match gltf_assets.get_mut(animation_resources.character_model.id()){
Some(res) => res,
_ => return,
};
if animations.len() == 0 || model.scenes.len() == 0{
return;
}
for anim in &animations{
model.animations.push(anim.clone());
}
for (k, v) in &named_animations{
model.named_animations.insert(k.clone(), v.clone());
}
let scene_root = SceneRoot(
model.scenes[0].clone(),
);
let (graph, node_indices) = AnimationGraph::from_clips([
animations[0].clone()
]);
let anim_idx = node_indices[0];
info!("indexces {:?}", node_indices);
// Keep our animation graph in a Resource so that it can be inserted onto
// the correct entity once the scene actually loads.
let handle = graphs.add(graph);
commands.insert_resource(Animations{
animations: node_indices,
graph_handle: handle.clone(),
});
let scene0 = model.scenes[0].clone();
// Fox
let entity = commands.spawn((
scene_root,
Transform::from_rotation(
Quat::from_euler(EulerRot::ZYX, 0.0, PI / 4.0, 0.0))
.with_scale(Vec3::new(20f32, 20f32, 20f32)
)
)).id();
if let Some(scene) = scenes.get_mut(scene0.id()){
let mut player = AnimationPlayer::default();
// 创建 AnimationTransitions 并启动动画
let mut transitions = AnimationTransitions::new();
transitions
.play(&mut player, anim_idx, Duration::ZERO)
.repeat();
let world = &mut scene.world;
world
.entity_mut(entity)
.insert(player)
.insert(transitions)
.insert(AnimationGraphHandle(handle));
}
else{
error!("没有找到scene {:?}", scene0.id());
}
info!("asset bind complete");
ACTIVE.store(false, std::sync::atomic::Ordering::Release);
}
fn keyboard_control(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut animation_players: Query<(&mut AnimationPlayer, &mut AnimationTransitions)>,
animations: Res<Animations>,
mut current_animation: Local<usize>,
) {
for (mut player, mut transitions) in &mut animation_players {
// info!("check player {:?}", player.name_at(0));
let Some((&playing_animation_index, _)) = player.playing_animations().next() else {
info!("playing animations is empty");
continue;
};
if keyboard_input.just_pressed(KeyCode::Space) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
info!("playing animation {:?}", playing_animation);
if playing_animation.is_paused() {
playing_animation.resume();
} else {
playing_animation.pause();
}
}
if keyboard_input.just_pressed(KeyCode::ArrowUp) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
let speed = playing_animation.speed();
playing_animation.set_speed(speed * 1.2);
}
if keyboard_input.just_pressed(KeyCode::ArrowDown) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
let speed = playing_animation.speed();
playing_animation.set_speed(speed * 0.8);
}
if keyboard_input.just_pressed(KeyCode::ArrowLeft) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
let elapsed = playing_animation.seek_time();
playing_animation.seek_to(elapsed - 0.1);
}
if keyboard_input.just_pressed(KeyCode::ArrowRight) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
let elapsed = playing_animation.seek_time();
playing_animation.seek_to(elapsed + 0.1);
}
if keyboard_input.just_pressed(KeyCode::Enter) {
*current_animation = (*current_animation + 1) % animations.animations.len();
transitions
.play(
&mut player,
animations.animations[*current_animation],
Duration::from_millis(250),
)
.repeat();
}
if keyboard_input.just_pressed(KeyCode::Digit1) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
playing_animation
.set_repeat(RepeatAnimation::Count(1))
.replay();
}
if keyboard_input.just_pressed(KeyCode::Digit2) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
playing_animation
.set_repeat(RepeatAnimation::Count(2))
.replay();
}
if keyboard_input.just_pressed(KeyCode::Digit3) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
playing_animation
.set_repeat(RepeatAnimation::Count(3))
.replay();
}
if keyboard_input.just_pressed(KeyCode::KeyL) {
let playing_animation = player.animation_mut(playing_animation_index).unwrap();
playing_animation.set_repeat(RepeatAnimation::Forever);
}
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I have a model named Feminine_TPose.gltf,and animationClip was saved in Feminine_TPose.gltf;
Now I want to load Feminine_TPose.gltf as entity Player, animations loaded from Feminine_TPose.gltf, then bind animations to Player then play;
I don't now how to do this, below is my code from example:
`
//! Plays animations from a skinned glTF.
`
but they wont work.
How can I make them work?
Beta Was this translation helpful? Give feedback.
All reactions