KirmesBude / bevy_trickfilm

bevy_trickfilm
Apache License 2.0
6 stars 3 forks source link

Get info about animation finished #14

Closed PraxTube closed 10 months ago

PraxTube commented 11 months ago

As far as I can tell, there is currently no method or field to check if an animation is finished. You can get the elapsed time, but it's a little clunky to use as you need to compare with the animation duration. I am not quite sure how this field would behave for repeating animations, I guess it just would always be false?

The reason I want this is to play an animation once, then play a looping animation once the anticipation animation is complete. It's a somewhat generic case that could also have it's own field, like repeat_from_frame or something where the user can specify a repeating animation that plays additional start up frames only ones. Probably not terribly hard to implement, but not sure what the scope of this crate is and if this falls into it.

KirmesBude commented 11 months ago

Yes, that is definitely something I want to see in crate. I am just not sure how far to go and what all the use cases are.

What you mentioned I would say is idle animations. An animation you want to return to if no other animation is still actively playing. I wonder if this should be a specific behaviour, where you give a default animation to the AnimationPlayer and it will fallback to that. Then again, the idle animation might not be as static as I assume here. E.g. in a topdown game you might have different "default animations" depending on the direction the character is facing.

Just having a way to query whether an animation is still playing or finished is certainly the first step though. But I wonder what this would look like in praxis.

fn go_to_idle_animation(
    mut animation_players: Query<&mut AnimationPlayer2D, With<IdentifyingComponent>>,
    some_animation: Res<SomeAnimation>,
) {
    for animation_player in &mut animation_players {
        if animation_player.finished() {
            animation_player.play(some_animation.0);
        }
    }
}

But to allow for more than just this one "conditionless transition" you would also need to know what animation is currently playing/has finished. We could also emit an Event containing the entity with the AnimationPlayer and a Handle.

KirmesBude commented 11 months ago

The reason I want this is to play an animation once, then play a looping animation once the anticipation animation is complete. It's a somewhat generic case that could also have it's own field, like repeat_from_frame or something where the user can specify a repeating animation that plays additional start up frames only ones. Probably not terribly hard to implement, but not sure what the scope of this crate is and if this falls into it.

I feel like this might touch on a different feature request. You could also just have 2 animations - one for the lead one, playing once and one for the looping part. Could you elaborate what advantages you see for your approach? If it was easier to model such transitions, would you still define just a single animation?

KirmesBude commented 11 months ago

I think I want to look into Unity/Godot/whatever to see how they handle this stuff and will try to come up with something. Feel free to open a PR for the is_finished functionality, if you want.

PraxTube commented 11 months ago

Just having a way to query whether an animation is still playing or finished is certainly the first step though. But I wonder what this would look like in praxis.

I feel like a finished() similar to paused() would do the job, so pretty much exactly what you have in the small example here.

Then again, the idle animation might not be as static as I assume here. E.g. in a topdown game you might have different "default animations" depending on the direction the character is facing.

This would definitely need to be quite sophisticated. I am not sure if I would like that to be in the animation player I am using as the user though, I am trying to compare this to the animation players you have in Unity or Godot where you set the direction flag and have your animation tree (or whatever it's called) select the right animation for you. I suppose you would define all of this in the ron file? Hm I am not sure, I guess a proof of concept would be necessary for me to see how this would work.

I feel like this might touch on a different feature request. You could also just have 2 animations - one for the lead one, playing once and one for the looping part. Could you elaborate what advantages you see for your approach? If it was easier to model such transitions, would you still define just a single animation?

So what I have is this animation, first 8 frames are spawning, last 8 frames are looping, it's all one single animation though. I implemented as two separate animations as said. I was working with sound a few hours before implementing it actually, and there you have the option to specify a looping sound from a given start point. Not sure how useful this actually is with sprite animations, but I just wondered if that is a generic enough case to support it in a crate.

It's not terribly hard to implement the animation switch, it's just is a little finicky as you need a timer to switch animations (or you can check if an animation is finished, in which case this would be a lot easier and way less ugly to implement). I guess this is a somewhat niche problem, a finished() flag would solve this on its own pretty much.

I think I want to look into Unity/Godot/whatever to see how they handle this stuff and will try to come up with something. Feel free to open a PR for the is_finished functionality, if you want.

Haha okay I see you have the same thought as I did.