use bevy::prelude::*; use bevy_spine::{ SkeletonController, SkeletonData, Spine, SpineBundle, SpineEvent, SpinePlugin, SpineReadyEvent, SpineSet, }; fn main() { App::new() .add_plugins((DefaultPlugins, SpinePlugin)) .add_systems(Startup, setup) .add_systems( Update, ( on_spawn.in_set(SpineSet::OnReady), on_spine_event.in_set(SpineSet::OnEvent), footstep_update, ), ) .run(); } fn setup( asset_server: Res, mut commands: Commands, mut skeletons: ResMut>, ) { commands.spawn(Camera2dBundle::default()); let skeleton = SkeletonData::new_from_json( asset_server.load("spineboy/export/spineboy-pro.json"), asset_server.load("spineboy/export/spineboy-pma.atlas"), ); let skeleton_handle = skeletons.add(skeleton); commands.spawn(SpineBundle { skeleton: skeleton_handle.clone(), transform: Transform::from_xyz(0., -200., 0.).with_scale(Vec3::ONE * 0.5), ..Default::default() }); } fn on_spawn( mut spine_ready_event: EventReader, mut spine_query: Query<&mut Spine>, ) { for event in spine_ready_event.read() { if let Ok(mut spine) = spine_query.get_mut(event.entity) { let Spine(SkeletonController { animation_state, .. }) = spine.as_mut(); let _ = animation_state.set_animation_by_name(0, "walk", true); } } } fn on_spine_event( mut spine_events: EventReader, mut commands: Commands, asset_server: Res, ) { for event in spine_events.read() { if let SpineEvent::Event { name, .. } = event { commands .spawn(Text2dBundle { text: Text::from_section( name.as_str(), TextStyle { font: asset_server.load("FiraMono-Medium.ttf"), font_size: 22.0, color: Color::WHITE, }, ) .with_justify(JustifyText::Center), transform: Transform::from_xyz(0., -200., 1.), ..Default::default() }) .insert(Footstep); } } } #[derive(Component)] struct Footstep; fn footstep_update( mut footstep_query: Query<(&mut Transform, &mut Text, Entity), With>, mut commands: Commands, time: Res