Unity - IEnumerator's yield return null

2019-02-10 10:06发布

问题:

I'm currently trying to understand IEnumerator & Coroutine within the context of Unity and am not too confident on what the "yield return null" performs. At the moment i believe it basically pauses and waits for the next frame and in the next frame it'll go back to perform the while statement again.

If i leave out the "yield return null" it seems the object will instantly move to its destination or perhaps "skip a lot of frames". So i guess my question is how does this "yield return null" function within this while loop and why is it necessary to have it.

void Start () {
    StartCoroutine(Move());
}

IEnumerator Move(){

    while (a > 0.5f){

        ... (moves object up/down)

        yield return null; // <---------
    }

    yield return new WaitForSeconds(0.5f);

    .... (moves object up/down)

    StartCoroutine(Move());
}

回答1:

The program will start the loop, if you had no yield, it simply runs all iteration within the same frame. If you had millions of iteration, then it would most likely block your program until all iterations are done and then continue.

When creating a coroutine, Unity attaches it to a MonoBehaviour object. It will run first on call fo the StartCoroutine until a yield is hit. Then it will return from the coroutine and place it onto a stack based on the yield. If null, then it will run again next frame. Some coroutine may WaitForEndOfFrame if they need to perform action at that specific moment. In some cases, you may start a timer like you did in the second case.

At that point, the coroutine is off, and the program is able to run the rest of it. On the next frame, Unity will find stacked coroutine and will call them from where they left off. If your loop never reaches a true condition, then you basically created an update method.

The purpose of coroutine is to perform actions that would span over a period without blocking the program.

IMPORTANT FACT: this is no multi-threading.



回答2:

You are correct. yield return null will wait until the next frame and then continue execution. In your case it will check the condition of your while loop the next frame.

The "why this is necessary" is probably because you want the object to move by an input every frame. Without yield return null it just executes trough the while loop in one frame.

More essential: It looks like you want to Update every frame and adjust the psoition. You could easily use the Update () for that. This function will get called by Unity every frame on an active script.