Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand this Unity Coroutine?

using UnityEngine;
using System.Collections;

public class CoroutineExample : MonoBehaviour
{
    IEnumerator Start ()
    {
        print ("Starting " + Time.time);
        yield return StartCoroutine (WaitAndPrint ());
        print ("Done " + Time.time);
    }

    IEnumerator WaitAndPrint ()
    {
        yield return new WaitForSeconds (5f);
        print ("WaitAndPrint " + Time.time);
    }
}

The result is

Starting 0
WaitAndPrint 5.010554
Done 5.010554

I have two questions?

First, How to understand the return value of function Start(). I used to see the return value of Start() is void. And in my view, Start() only executes once (one frame) by Unity, but yield return seems make Start() function execute in two frames;

Second, I am also confused by the result. I think the result should be

Starting 0
Done 5.010554
WaitAndPrint 5.010554

Because StartCoroutine() starts the function WaitAndPrint(). In function WaitAndPrint(), yield return makes this function pause in this frame and return to Start(). Then Start() continues going on and prints "Done xxxxx". After 5 seconds, WaitAndPrint() resume and prints "WaitAndPrint xxxxx".

Where am I wrong?

like image 757
mingchaoyan Avatar asked Feb 17 '26 23:02

mingchaoyan


2 Answers

When you call yield return the control is taken by Unity.

When you start a Coroutine Unity will take the IEnumerator returned by the method and will call MoveNext on the IEnumerator returned.

Based on the type of object and on the values in the object Unity will decide what to do.

In you case in the Start method the yield statement return another IEnumerator so Unity will not call MoveNext on the Start returned object until the second IEnumerator finishes.

In WaitAndPrint the first MoveNext returns a WaitForSeconds object, based on that Unity decides that it will not call MoveNext on in until 5 seconds have passed. After 5 seconds it calls MoveNext again and the rest of the method is executed, which is just this line

print ("WaitAndPrint" + Time.time);

As the IEnumerator returned by yield return StartCoroutine (WaitAndPrint ()); reached its end it will call MoveNext on the IEnumerator that was returned by Start, this in turn will execute what ever is left of Start:

print ("Done " + Time.time);

Hope this is clear enough :)

like image 56
Radu Diță Avatar answered Feb 20 '26 13:02

Radu Diță


Here's how I understand this result :

The Start() function is called once by Unity and prints "Started".

Then the following line does two things :

yield return StartCoroutine (WaitAndPrint ());
  • it starts the WaitAndPrint() coroutine
  • it waits for it to be over before continuing in the Start() coroutine.

The WaitAndPrint() coroutine will do its stuff :

  • Wait for 5 seconds
  • Print "WaitAndPrint" + time

Then the Start() coroutine will resume and print "Done" + time.

This is why

print ("WaitAndPrint" + Time.time);

is printed before :

print ("Done " + Time.time);

Also, you should edit your post, it misses a space in the first result :

WaitAndPrint5.010554

Should be

WaitAndPrint 5.010554

Sorry if it's not clear, it's my first time answering on StackOverflow, hope it helped !

like image 45
OuiMerci Avatar answered Feb 20 '26 13:02

OuiMerci



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!