[Basic Unity3D tutorial] Unity tutorial for beginners (5): Detailed description of Coroutine in Unity3D)

Source: Internet
Author: User

Author: Wang Xuan Yi, source: http://www.cnblogs.com/neverdie/Reprinted, Please keep this statement. If you like this article, click [recommendation ]. Thank you!

Private IEnumerator Test () {WWW www = new WWW (ASSEST_URL); yield return www; AssetBundle bundle = www. assetBundle ;}What is coroutine?

From the perspective of program structure, Coroutine is a finite state machine, which may not be quite clear. When talking about Coroutine, we need to mention another thing, that is, Subroutine, which generally refers to a function.StatusAfter it returns, all its local variables will disappear, but in the coroutine we canMultiple times in a function,The local variables are stored as States in the coroutine function, and the last return is known before the coroutine state is cleared.

In short, coroutine is: you can write a sequence of code, and then indicate where to pause. Then, after the next frame or a period of time, the system will continue to execute this code.

How to Use coroutine?

A simple C # code is as follows:

IEnumerator LongComputation () {while (someCondition) {/* do a series of work * // pause here and continue execution next frame
        yield return null;    }}
How does coroutine work?

Pay attention to the code example above. You will find that the return value of a coroutine function is IEnumerator, which is an iterator. You can regard it as a pointer to a node in a sequence, it provides two important interfaces: Current (returns the elements currently pointed to) and MoveNext () (moves the Pointer Forward to a unit, and returns true if it moves successfully ). IEnumerator is an interface, so you don't have to worry about the specific implementation.

Generally, if you want to implement an interface, you can write a class, implement members, and so on.Iterator block)Is a convenient way to implement IEnumerator without any trouble-you just follow some rules and implement IEnumerator automatically generated by the compiler.

An iterator has the following features:

So what is the yield keyword? It declares the next value in the sequence or a meaningless value. If yield x (x indicates a specific object or value) is used, movenext returns true and current is assigned x. If yield break is used, movenext () returns false.

For example, this is an iterator block:

public void Consumer(){    foreach(int i in Integers())    {        Console.WriteLine(i.ToString());    }}public IEnumerable<int> Integers(){    yield return 1;    yield return 2;    yield return 4;    yield return 8;    yield return 16;    yield return 16777216;}

Note that during the iteration process, you will find that the code between two yield runs the next yield only after the execution is completed. In Unity, we have used this point, we can write the following code as an iterator:

 

 
IEnumerator TellMeASecret(){  PlayAnimation("LeanInConspiratorially");  while(playingAnimation)    yield return null;   Say("I stole the cookie from the cookie jar!");  while(speaking)    yield return null;   PlayAnimation("LeanOutRelieved");  while(playingAnimation)    yield return null;}

Then we can use the following Customer Code to call the above program to achieve latency.

IEnumerator e = TellMeASecret();
while(e.MoveNext()) {     // do whatever you like}
How does coroutine implement latency?

As you can see, the value returned by yield return is not necessarily meaningful, such as null, but we are more interested in how to use the return value of yield return to achieve some interesting results.

Unity declares YieldInstruction as the base class of all returned values, and provides several common inheritance classes, such as WaitForSeconds (paused for a period of time ), waitForEndOfFrame (paused to the next frame for execution. What's more clever is that yield can also return A Coroutine body. When Coroutine A returns A Coroutine Bbody, it will wait until B completes and then execute. The following is a detailed description:

 

Normal coroutine updates are run after the Update function returns. A coroutine is a function that can suspend its execution (yield) until the given YieldInstruction finishes. Different uses of Coroutines:yield; The coroutine will continue after all Update functions have been called on the next frame.yield WaitForSeconds(2); Continue after a specified time delay, after all Update functions have been called for the frameyield WaitForFixedUpdate(); Continue after all FixedUpdate has been called on all scriptsyield WWW Continue after a WWW download has completed.yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to complete first.

 

The key code for implementing latency is in StartCoroutine. I thought I had never seen the source code of Unity, so I can only guess that the internal structure of StartCoroutine should be like this:
List<IEnumerator> unblockedCoroutines;List<IEnumerator> shouldRunNextFrame;List<IEnumerator> shouldRunAtEndOfFrame;SortedList<float, IEnumerator> shouldRunAfterTimes; foreach(IEnumerator coroutine in unblockedCoroutines){    if(!coroutine.MoveNext())        // This coroutine has finished        continue;     if(!coroutine.Current is YieldInstruction)    {        // This coroutine yielded null, or some other value we don't understand; run it next frame.        shouldRunNextFrame.Add(coroutine);        continue;    }     if(coroutine.Current is WaitForSeconds)    {        WaitForSeconds wait = (WaitForSeconds)coroutine.Current;        shouldRunAfterTimes.Add(Time.time + wait.duration, coroutine);    }    else if(coroutine.Current is WaitForEndOfFrame)    {        shouldRunAtEndOfFrame.Add(coroutine);    }    else /* similar stuff for other YieldInstruction subtypes */} unblockedCoroutines = shouldRunNextFrame;

Of course, we can also add various subclasses for YieldInstruction. For example, yield return new WaitForNotification ("GameOver") is easy to think of to wait for a message to trigger, for details about the message mechanism of Unity, refer to this article: [Unity3D skills] use the event/delegate mechanism (event/delegate) in Unity for GameObject communication (2): Introduce the middle layer icationicationcenter.

What more fun?

The first interesting thing is that yield return can return any YieldInstruction, so we can add some conditions here:

YieldInstruction y; if(something) y = null;else if(somethingElse) y = new WaitForEndOfFrame();else y = new WaitForSeconds(1.0f); yield return y;

Second, because a coroutine is justIterator BlockYou can also traverse it by yourself, which is useful in some scenarios, for example, when determining whether to execute a coroutine by adding conditions:

IEnumerator DoSomething(){  /* ... */} IEnumerator DoSomethingUnlessInterrupted(){  IEnumerator e = DoSomething();  bool interrupted = false;  while(!interrupted)  {    e.MoveNext();    yield return e.Current;    interrupted = HasBeenInterrupted();  }}

Third, because coroutine can be yield coroutine, we can create a coroutine function by ourselves, as shown below:

IEnumerator UntilTrueCoroutine(Func fn){   while(!fn()) yield return null;} Coroutine UntilTrue(Func fn){  return StartCoroutine(UntilTrueCoroutine(fn));} IEnumerator SomeTask(){  /* ... */  yield return UntilTrue(() => _lives < 3);  /* ... */}
Summary

Most of this article is translated from this blog. This is the best blog I have ever seen about Coroutine. So I have translated it and shared it with you. I hope you like it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.