Play animation forward than immediately backwards, once (ie single pingpong)

Is there a way to play a single ping pong of an animation. I have an animation of a hand reaching out. Using pingpong, it reaches forwards and then back, which is what I want. But I only want it to happen once, not continually loop forever.

Is there an easier/better way to do this than by playing it once, and once it reaches the end, playing it again backwards?

I've currently set it to pingpong, and am watching until time gets > than length * 2. But this seems like a stupid way to do it...

2 Answers

2

once you start the animation, you can check it using animation.normalizedTime:

function Grab(){
animation["grab"].Play();
while(animation["grab"].normalizedTime < .1)
yield; //just making sure anim has started, there may be a prettier way to do this, but it'll work
if(animation["grab"].normalizedTime == 0) //back to the first frame
animation["grab"].Stop();
}

normalizedTime is a float, from 0 (the first frame) to 1 (the last frame)

I wonder if you'd actually be able to catch it at normalizedTime == 0, considering it'll immediately start counting up again (as it starts into the next iteration). But I didn't know about normalizedTime before, so that's good to note.

when it hits that frame, it should register I'm sure, but I can't say 100%, haven't actually tested this

I hit situations where Stop was not called using fast or short animations. See my notes and updated solution below.

Thank you, Seth, for your idea to use animation timing to control how many times the anim plays. Unfortunately, though, I encountered situations where the code set above never triggered the stop, specifically with fast or short animations.

I implemented a simplified version of Seth’s concept to stop more reliably and precisely using 2X the duration of the animation. Here it is in C#:

    // Play, crossfade, or blend into your animation here 
    animation.CrossFade(animationName);    
    StartCoroutine("PingPingOnce", animName);

    IEnumerator PingPingOnce(string animationName)
    {
        animation[animationName].wrapMode = WrapMode.PingPong;
    
        // Wait for a forward and backwards animation play
        yield return new WaitForSeconds(animation[animationName].length*2/animation[animationName].speed);
    				
        animation.Stop();
    }