Hello Guest

Author Topic: How to check the current animation frame via code  (Read 11263 times)

fryza

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 22
    • View Profile
How to check the current animation frame via code
« on: April 05, 2013, 02:27:25 pm »
I am building a game like this:
http://www.youtube.com/watch?v=KJ3_-IjkSSE

The lights go around and the player "stops" it and tries to hit the jackpot light.

I have 25 lights/images in the animation.

Light # 12 is the winning animation. 

This is the pseudocode for what I need:

if (stopButtonPressed)
{
    if (animationFrame == 12)
    {
        //Then we just won
    }

}

I'm not sure how to do this with 2D Toolkit - any thoughts?


unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to check the current animation frame via code
« Reply #1 on: April 05, 2013, 02:33:49 pm »
You can't directly but its easy enough to implement.
Assuming the clip is looped:

Code: [Select]
int frame = (int) (( anim.ClipTimeSeconds * anim.ClipFps ) % anim.CurrentClip.frames.Length );
I'll add a helper function for this in a future version. The reason it wasn't there in the first place is to avoid relying on frame numbers but rather time which makes a lot more sense for seamlessly transitioning looped animations, but in this case, you really do want to know what frame is currently visible.

The other option is to look at what sprite is currently visible, which can work too.
Code: [Select]
if(anim.CurrentSprite.name == "name of frame 12") {
}

fryza

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: How to check the current animation frame via code
« Reply #2 on: April 05, 2013, 02:35:05 pm »
Brilliant! Thanks for the amazingly fast support!

fryza

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: How to check the current animation frame via code
« Reply #3 on: April 12, 2013, 02:49:26 pm »
You can't directly but its easy enough to implement.
Assuming the clip is looped:

Code: [Select]
int frame = (int) (( anim.ClipTimeSeconds * anim.ClipFps ) % anim.CurrentClip.frames.Length );
I'll add a helper function for this in a future version. The reason it wasn't there in the first place is to avoid relying on frame numbers but rather time which makes a lot more sense for seamlessly transitioning looped animations, but in this case, you really do want to know what frame is currently visible.

The other option is to look at what sprite is currently visible, which can work too.
Code: [Select]
if(anim.CurrentSprite.name == "name of frame 12") {
}

Hi unikron,
Your code here worked so thanks!

But I do have another problem along these same lines.

I have a td2kButton.  I call "StopButtonPressed" on a script from that button.

The problem is the anim doesn't stop exactly when I press the button. I get about a .5 second delay. There are 70 frames in my animation. #70 is the jackpot.  If I press the stop button on lets say frame 39 the anim actually doesn't stop until about frame 45.  How can I make this more precise - this is pretty far off.

I did some precise calculations - I set the current frame (after pausing) to be -4 from the current frame and it landed exactly where I clicked. So this definitely looks like a delay issue. Any way of enhancing the speed of the Pause command? Or maybe it is the speed of the method call on the button.

Here is my code:
Code: [Select]
public tk2dAnimatedSprite Track;

private bool animPlaying;

// Use this for initialization
void Start ()
{
StartAnim();
}

// Update is called once per frame
void Update () {

}

public void StopButtonPressed()
{
if (animPlaying)
{
Track.Pause();
animPlaying = false;
}
else
{
animPlaying = true;
Track.Play();
}
}

public void StartAnim()
{
animPlaying = true;
}
« Last Edit: April 12, 2013, 03:26:07 pm by fryza »

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to check the current animation frame via code
« Reply #4 on: April 13, 2013, 01:26:40 pm »
I think this is to do with the scale animations you see when the button is pressed. If you turn them off, response should be much better.

The variables are visible in the inspector. (scaletime & press wait time).

fryza

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: How to check the current animation frame via code
« Reply #5 on: April 13, 2013, 06:16:23 pm »
So removing the animation time did help - but still wasn't quick enough. I resorted to a raycast (instead of the button script) and the speed was perfect.


I do have one more question along these lines - my animation has 69 frames. I want the animation to complete in 1.8 seconds.

The problem I am having is sometimes some of the frames are being skipped.  For instance our animation has 69 different "lights". One of those lights is a jackpot light (frame 68). When frame 68 plays, it lights up red. The problem is not all frames are getting played. And it is different every time.  This is what I am seeing in my logs:

Frame 0
Frame 1
Frame 3
Frame 4
Frame 5
Frame 6
Frame 7
Frame 9
Frame 11
Frame 12

etc etc


How do I ensure every frame is played?

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to check the current animation frame via code
« Reply #6 on: April 14, 2013, 03:21:09 pm »
The problem here looks like its to do with screen refresh rate vs animation playback rate.

1. Make sure your screen is vsync locked to whatever refresh rate you want to use.
2. Make sure your animation is at a correct multiple of it.

If your animation has 69 frames and you want it to play in 1.8s - 69/1.8 = 38.3333 fps.
Your screen would have to run at this refresh rate exactly for it to work properly, otherwise it is likely to skip frames for one reason or other.

If you MUST display every frame, VSYNC lock your game, set Time.captureFrameTime = your target frame time, and Unity will not change deltaTime every frame. Then, make sure your animation will display properly at that frame rate, i.e. the frame rate of the animation must be divisible by your target framerate. Otherwise you have no guarantees of each frame 100% DEFINITELY playing if all those cases are not met.

fryza

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: How to check the current animation frame via code
« Reply #7 on: May 01, 2013, 02:33:53 am »
Thanks for this. It works perfectly now.

rbisso

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: How to check the current animation frame via code
« Reply #8 on: May 22, 2013, 07:57:30 am »
unikronsoftware, I'd strongly second the need for a currentFrame property in order for the toolset to be as flexible as possible. I'm making a game where a central timer is updating the animations for each AI via spaced-out "ticks", and I want to drive the animations that way. I currently have them paused and am setting the frames directly, so the above timer-derived solution does not seem to work, and I don't want to hardcode the frame names.

In this type of situation, it'd be super helpful and very direct to have a property that we could access to tell us the current frame for the current clip.

Your desire to funnel users into using time is understandable, but it may just be a simpler and more user-friendly solution to provide the flexibility of having the property accessor, while at the same time advising users in the docs on how they'd typically get the best results (via a timer).

Thanks so much for your hard work... overall super happy with 2D Toolkit! :)

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: How to check the current animation frame via code
« Reply #9 on: May 22, 2013, 12:21:02 pm »
I gave in to this a while ago :)
2D Toolkit 2.0 has a tk2dSpriteAnimator.CurrentFrame property which you can use to read the current frame.