Johannes
Johannes

Reputation: 440

StartCoroutine overhead vs Invoke (Unity3D)

I am comparing StartCoroutine and Invoke in a Method that should be execute in a specific time. To my understanding these two functions should take the same time (1 sec). Calling the first method with invoke completes in about 1sec, using a coroutine takes almost 2 seconds! How can that be?

private void iincrease_arrow_invoked(){
    if (arrow.transform.localScale.x <= 1f) {
        arrow.transform.localScale = new Vector3 (arrow.transform.localScale.x + 0.01f, arrow.transform.localScale.y, arrow.transform.localScale.z);
        Invoke ("iincrease_arrow_invoked", 0.01f);
    } 

}

IEnumerator increase_arrow_coroutine(){

    yield return new WaitForSeconds (0.01f);
    if (arrow.transform.localScale.x <= 1f) {
        arrow.transform.localScale = new Vector3 (arrow.transform.localScale.x + 0.01f, arrow.transform.localScale.y, arrow.transform.localScale.z);
        StartCoroutine (increase_arrow_coroutine ());
    } 

}

Upvotes: 1

Views: 5880

Answers (2)

Brian Miller
Brian Miller

Reputation: 1

Well, technically it's quite different since you are waiting a full second before doing anything at all in the coroutine, and then you do it, and when it executes itself again there you are waiting another full second. The Invoke call is executed immediately since you didn't put a delay on that like in the coroutine, and then you ask it to wait 1 second and repeat. If you want the coroutine to behave the same, then code it the same, and put the delay at the end.

A diagram would help: StartCoroutine ->>> wait 1 second ->>> do the work ->>> wait 1 second when repeated.

What you want is this: StartCoroutine ->>> do the work ->>> wait 1 second ->>> do the work when repeated

It only appears to be taking 2 seconds the way you have it.

This is more what it should look like before even beginning to compare them:

WaitForSeconds delay = new WaitForSeconds(0.01f);

IEnumerator increase_arrow_coroutine() {
    if(arrow.transform.localScale.x <= 1.0f) {
        arrow.transform.localScale = new Vector3(
            arrow.transform.localScale.x + 0.01f, 
            arrow.transform.localScale.y,
            arrow.transform.localScale.z);
    }

    yield return delay;

    StartCoroutine(increase_arrow_coroutine());
}

To me it still doesn't make much sense that it takes that long for you unless you have other delays somewhere else. It should only take 0.01 seconds, but that's another story.

Upvotes: 0

user3071284
user3071284

Reputation: 7100

The IEnumerator is likely running more than once, while the invoked function is only running once. In your code, you're allowing the IEnumerator to be run multiple times by also calling StartCoroutine inside the IEnumerator.

Comparing InvokeRepeating with your existing IEnumerator would be a cleaner comparison.

Upvotes: 1

Related Questions