-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[QOL] Specify an animation to run after a Once
animation finishes
#104
Comments
Yeah, definitely, that sounds like a good idea. Maybe can you share more details about your current use-case? So that I can try thinking about an API. |
So imagine you're making a tile-based game. You're gonna be swapping the animations a lot.
In some cases, like an attack, you'll play the attack animation once and then return to the animation you were playing before you attacked. Here's some musing: An
And then that allows you to expand the AnimationChainBuilder to support options other than Or maybe something like
I hope this helps! Let me know if you want to chat about it |
Yes, it helps, thanks. I will think more about it and try to come up with an initial design. |
I've chosen to use |
Using bevy-simple-state-machine as a reference I was able to implement something that works for Here's the crux of the code. Also, pub fn check_animation_transitions(
mut state_machines_query: Query<(Entity, &mut AnimationStateMachine)>,
mut event_writer: EventWriter<TransitionEndedEvent>,
animations: Res<Assets<Animation>>,
) {
for (entity, mut state_machine) in &mut state_machines_query {
if let Some(current_state) = state_machine.current_state() {
if current_state.interruptible || state_machine.animation_finished() {
for transition in state_machine.transitions_from_current_state() {
if transition.trigger.evaluate(&state_machine.variables) {
if let Some(next_state) =
state_machine.get_state(transition.end_state.unwrap())
{
println!("triggering {}", transition);
state_machine.current_state = next_state.name;
// Get new animation and restart benimator with it
let animation = match animations.get(&next_state.base_animation) {
Some(anim) => anim,
None => continue,
};
state_machine.base_frame.reset();
state_machine
.base_frame
.update(animation, Duration::from_millis(0));
// emit event that the transition has completed
event_writer.send(TransitionEndedEvent {
entity,
origin: current_state.state_ref(),
end: transition.end_state,
});
}
}
}
}
}
}
}
pub fn update_animations(
time: Res<Time>,
mut state_machines_query: Query<(&mut AnimationStateMachine, &mut TextureAtlasSprite)>,
animations: Res<Assets<Animation>>,
) {
for (mut state_machine, mut sprite_texture) in &mut state_machines_query {
if let Some(current_state) = state_machine.current_state() {
// Get animation and update it
let animation = match animations.get(¤t_state.base_animation) {
Some(anim) => anim,
None => continue,
};
state_machine.base_frame.update(animation, time.delta());
sprite_texture.index = state_machine.base_frame.frame_index();
}
}
} |
Thanks @bmanturner, I'll have to look into this. Right of the bat, I would like to make sure you're aware that benimator is no longer a bevy plugin. The bevy systems you just shared are still interesting to look at, and it is indeed worthwhile to think about how usage from bevy would look like. I will definitely study what you shared. I just want to make sure you're aware I am looking for an API that is agnostic of bevy. |
Yeah I dig. Aside from those systems the rest of the code in the repo is agnostic. Worth a look! I put my code here because I’ve seen this issue linked to in bevy discords more than once so I think it might help people that come here and are wondering about implementing that functionality. |
Would be great to queue up a new animation, or specify a default animation to run once one finishes
The text was updated successfully, but these errors were encountered: