cateb
cateb

Reputation: 21

I do not know if I used too much 'yield return new WaitForSeconds' in the coroutine function

** Unity5.6.5f1 / C#

I used a coroutine to run the animation.

Rather than creating multiple if statements in the update function,

I thought coroutine would be better.

But I think I used 'yield return new WaitForSeconds' too much,

Is it common to write coroutines this way?

private IEnumerator AnimationControl()
{
    yield return new WaitForSeconds(41f);        
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return new WaitForSeconds(5.667f);        
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");

    yield return new WaitForSeconds(3.666f);
    objAni.Play("Fire01");

    yield return new WaitForSeconds(2.334f);
    obj3Ani.Play("Panic");
    obj2Ani.gameObject.SetActive(false);

    yield return new WaitForSeconds(8.333f);
    objAni.Play("Fire02");

    yield return new WaitForSeconds(6.333f);      
    objAni.Play("Fire03");

    yield return new WaitForSeconds(6.1337f);       
    obj3Ani.Play("Stay");
    objAni.Play("Stay");

    yield return new WaitForSeconds(3.2003f);        
    obj3Ani.Play("Surprise02");
    objAni.Play("Surprise");

    yield return new WaitForSeconds(3.333f);                
    obj3Ani.Play("Run");
    objAni.Play("Run");

    yield return new WaitForSeconds(6f);
    objAni.Play("Stay");

    yield return new WaitForSeconds(1.667f);      
    objAni.Play("Run");

    yield return new WaitForSeconds(2.333f);        
    obj3Ani.gameObject.SetActive(false);

    yield return new WaitForSeconds(0.667f);        
    objAni.gameObject.SetActive(false);

    yield return new WaitForSeconds(1.333f);
    textObj.SetActive(false);

    yield return new WaitForSeconds(2.667f);
    endingObj.SetActive(true);
    allObj.SetActive(false);
}

Thanks for reading.

Upvotes: 1

Views: 837

Answers (1)

Programmer
Programmer

Reputation: 125305

This is exactly what coroutine is used for, which is to execute many code sequentially and even wait anytime. It's not really too much. The only issue I see is creating new WaitForSeconds every time. If you know the time to wait or you hard-coded the times, declare the WaitForSeconds outside the function then yield against them. This really depends on how often you call the AnimationControl function.

For example,

private IEnumerator AnimationControl()
{
    yield return new WaitForSeconds(41f);
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return new WaitForSeconds(5.667f);
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");
}

becomes

WaitForSeconds wTime1 = new WaitForSeconds(41f);
WaitForSeconds wTime2 = new WaitForSeconds(5.667f);

private IEnumerator AnimationControl()
{
    yield return wTime1;
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return wTime2;
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");
}


If you really want to reduce the WaitForSeconds code, you can make a wrapper class around it. This class should hold the time to wait or even better, WaitForSeconds instance then use Action to represent the code you want to execute after the wait. Create a List of this class, loop over it, wait then execute the code in the Action variable.

The Wrapper class:

public class AnimControlInfo
{
    public WaitForSeconds waitTime;
    public Action action;
}

Create a List of it:

List<AnimControlInfo> animInfo = new List<AnimControlInfo>();

Initialize the List so that it can be used in the AnimationControl function:

void InitControlAnimInfo()
{
    AnimControlInfo aI1 = new AnimControlInfo();
    aI1.waitTime = new WaitForSeconds(41f);
    aI1.action = delegate
    {
        objAni.gameObject.SetActive(true);
        obj2Ani.gameObject.SetActive(true);
        obj3Ani.gameObject.SetActive(true);
        objAni.Play("Stay");
        obj2Ani.Play("Stay");
        obj3Ani.Play("Stay");
    };

    AnimControlInfo aI2 = new AnimControlInfo();
    aI2.waitTime = new WaitForSeconds(5.667f);
    aI2.action = delegate
    {
        objAni.Play("Run");
        obj2Ani.Play("Run");
        obj3Ani.Play("Action");
    };

    //Add to List
    animInfo.Add(aI1);
    animInfo.Add(aI2);
}

Then your new AnimationControl function to wait and play animation or activate/de-activate GameObects:

private IEnumerator AnimationControl()
{
    //Loop over the List, wait then do action
    for (int i = 0; i < animInfo.Count; i++)
    {
        yield return animInfo[i].waitTime;
        if (animInfo[i].action != null)
            animInfo[i].action();
    }
}

The amount of code in the AnimationControl function has been reduced. It also reduced the excessive use of the WaitForSeconds class.

Upvotes: 2

Related Questions