DramboHero
DramboHero

Reputation: 1103

unity - play animations one at a time

I have a coroutine function that looks something like that:

// Replacing on start game
public virtual void Replace()
{
    StartCoroutine(ReplaceCoroutine());
}

// the Replacing animation
private IEnumerator ReplaceCoroutine()
{
    // check if the piece has an animation attached
    Animator animator = GetComponent<Animator>();
    if (animator)
    {
        animator.Play(clearAnimation.name);
        yield return new WaitForSeconds(clearAnimation.length);
    }
}

and I activate it with a loop like so:

// mixing pieces
for (int i = 0; i < 5; i++)
{
    pieces[i].Replace();
}

The problem is that the loop goes all at once, and everything animates at the same time. I want to make sure, that pieces[2] for example, will start he's animation coroutine only when pieces[1] got to half of it's time in the animation.

is it possible?

thank you

Upvotes: 0

Views: 876

Answers (2)

avariant
avariant

Reputation: 2300

If you want to control each piece relative to the previous one (half the animation time as mentioned), you want your coroutine to yield after each piece operation but do it all in one single coroutine, not a separate coroutine for each piece.

public IEnumerator ReplaceCoroutine()
{
     for(int i=0; i<pieces.Length; i++)
     {
         // check if the piece has an animation attached
         Animator animator = pieces[i].GetComponent<Animator>();
         if (animator!=null)
         {
            animator.Play(pieces[i].clearAnimation.name);
            yield return new WaitForSeconds(pieces[i].clearAnimation.length/2.0f);
         }
    }
}

void startAnimationSequence
{
    StartCoroutine(ReplaceCoroutine());
}

This will kick off each piece's animation sequentially and then wait for half the animation time before looping to the next. Just call startAnimationSequence to start the loop.

Upvotes: 0

Programmer
Programmer

Reputation: 125265

You have to call your

for (int i = 0; i < 5; i++)
{
    pieces[i].Replace();
}

from another coroutine function then wait for each coroutine function to return. You do that by yielding the StartCoroutine function call. The code below will call yourCoroutineFunction function and then wait for it to finish before running the next loop.

for (int i = 0; i < 5; i++)
{
    yield return StartCoroutine(yourCoroutineFunction());
}

I can't tell where your functions are placed but below should work for you. If not, use the example above to fix your problem.

public IEnumerator ReplaceCoroutine()
{
    // check if the piece has an animation attached
    Animator animator = GetComponent<Animator>();
    if (animator)
    {
        animator.Play(clearAnimation.name);
        yield return new WaitForSeconds(clearAnimation.length);
    }
}

IEnumerator playAll()
{
    for (int i = 0; i < 5; i++)
    {
        yield return pieces[i].StartCoroutine(ReplaceCoroutine());
    }
}

Then to call it, use StartCoroutine(playAll());

Upvotes: 1

Related Questions