The Coroutine in unity is achieved through yield expression; This code is seen everywhere in the official script.
Questions:
What is yield?
What is Coroutine?
What's so strange about Unity's coroutine program execution process?
What is the principle of coroutine in unity and how is it implemented?
What issues do you need to be aware of when using unity Coroutine?
One, yield of the program execution characteristics in several languages :
The yield in Lua is to suspend and pass parameters to the resume, which is the function of the cooperative functions. Resume enables the cooperative function to hang and run and pass parameters to the synergistic function.
The yield return/break in C # is used to return the values (like iterations) inside the function query collection generator and record the current scene, and continue execution from the yield field of the last record at the next query, until the execution continues without, then exit this yield logic. Yield break terminates the yield iteration logic and jumps out.
Yieldimplementation:
1). Caller callsfunction
2). Caller Requestsitem Request an element on demand
3). Next itemreturned returns the requested element
4). Goto Step #2
In Python, yield expression, the function of yield has become a generator, call the function to return an iterator object, call the next method with an iterator object (or automatically call the next method in the loop), start executing the function, execute to yield Expression breaks, returns the current value of the iterator, preserves the scene, and the next call to next is executed from the field, and the iteration is finished. You can see that yield in Python is similar to yield in C #, to create a generator, to break the value of an iterator when executing, and to record the scene and continue the execution next time from the field.
The yield in unity is similar to that in C#,python, because unity is based on the. NET Framework, and the unity script begins with Boo (a variant of Python). It's just that unity has more coroutine attribute types, and Startcoroutine's coroutine management classes. Instead of starting a new thread, Startcoroutine starts a synergistic program, and the default unity all code is in one line approached (http://answers.unity3d.com/questions/280597/ new-thread-vs-startcoroutine.html).
second, Unity's coroutine implementation phenomenon :
The first method:
Voidstart ()
{
Print ("starting" +time.time);----------------------------------------1
Startcoroutine (Waitandprint (2));-------------------------------------2
Print ("Done" +time.time);-------------------------------------------3
}
IEnumerator Waitandprint (float waitTime)
{
Yield return new waitforseconds (waitTime);------------------------4
Print ("Waitandprint" + time.time);----------------------------------5
}
The sequence of execution of this code is 12435
IEnumerator Start ()
{
Print ("starting" +time.time);----------------------------------------1
Yield return Startcoroutine (Waitandprint (2.0F));------------------------2
Print ("Done" +time.time);------------------------------------------3
}
IEnumerator Waitandprint (float waitTime)
{
Yield return new waitforseconds (waitTime);----------------------------4
Print ("Waitandprint" + time.time);-----------------------------------------5
}
The sequence of execution of this code is 12453
Why? Such a strange way of doing it.
Third,the unity Official document to Coroutine explanation :
Normal coroutine Updates is run after Theupdate function returns . Acoroutine is a function of can suspend its execution (yield) until the givenyieldinstruction finishes. Different uses of coroutines:
yield ; The coroutine would continue after all Update functionshave been calledon thenext frame.
yield Waitforseconds (2) ; Continueaftera specified time delay, the After all Update functions has been called for Theframe.
yield waitforfixedupdate () ; Continueafter allfixedupdate have been called on all scripts.
yield WWW . Continue After a WWW download has completed .
yield Startcoroutine (MyFunc); Chains the Coroutine, and would wait for the MyFunc coroutine to Completefirst .
C # to add the return keyword between yield coroutine.
Iv. The Coroutine principle in unity guesses :
virtual machine staging mechanism, the same type of nested stack storage implementation of serial execution :. NET virtual machines in each frame loop, they go to each compiler's pre-defined portals in turn. For the coroutine type, the compiler needs to generate some code coroutine ( Coroutine iterator multiple management classes manage each coroutine, Coroutine coroutine .net The virtual machine is tagged with a function pointer to manage the field and periodically check the time in the process or the event occurs after the message is met, and all rights are given to yield interrupted scene ) yield After the break the code continues to execute , which creates a function that we see to .
For nested coroutine types, they are executed serially rather than in parallel, and possibly. NET virtual machines are stored on stacks with the same coroutine type, and the top of the stack is executed first, thus implementing serial execution , if the outer layer does not use yield return, it will not be executed serially, but executed in parallel.
Schematic diagram:
See: http://www.richardfine.co.uk/2012/10/unity3d-monobehaviour-lifecycle/
V. Issues to be aware of when using coroutine in unity:
1. Place of use and place of inability to use:
Yield coroutine must be called in Monobehaviour or classes that inherit from Monobehaviour. Yield cannot be used in update or fixedupdate.
2. Open the co-process:
Startcoroutine (String methodName) and Startcoroutine (Ienumeratorroutine) can open a co-process,
Difference:
When using a string as a parameter, only one parameter can be passed at most when the process is turned on, and the performance consumption will be greater. The use of IEnumerator as a parameter does not have this limitation.
3. Delete the process:
1). In Unity3d, use Stopcoroutine (stringmethodname) to terminate the Monobehaviour a cooperative program that specifies the method name, using the Stopallcoroutines () To terminate all of the monobehaviour that can be terminated by this agent.
Including Startcoroutine (IEnumerator routine).
2). There is also a way to terminate the cooperative program, the active property of the Gameobject is set to False, when the active is set to Ture again, the co-program will not be opened;
This does not take effect if you set the enabled script for the collaboration program to false.
Differences in use between 4.js and C #:
Yield return instead of yield is used in C #.
The yield (break) statement in C # must be in the IEnumerator type, the return type of the C # method is IEnumerator, and the return value such as (Eg:yield return new Waitforseconds (2); or yield returnnull);
5. function return value and parameter type, combined design pattern:
The return type of the synergistic program is the Coroutine type. In Unity3d, the Coroutine class inherits from Yieldinstruction, so the return type of the co-program can only be null, the number of frames waiting (frame), and the waiting time.
The parameters of the synergistic program cannot specify ref, out parameters. However, when we use the WWW class, we often use the cooperative program, because the parameter address (reference) cannot be passed in the cooperative program, and the object cannot be output.
This makes it possible to rewrite a co-program for each WWW object that is downloaded, and the solution to this problem is to create a WWW-based class ( solved with a combination pattern ) and implement a download method. As follows:
Using Unityengine;
Using System.Collections;
public class Wwwobject:monobehaviour
{
public www www;
Public wwwobject (string url)
{
if (Gamevar.wwwcache)
www = WWW.LoadFromCacheOrDownload (URL, gamevar.version);
Else
www = new www (URL);
}
Public IEnumerator Load ()
{
Debug.Log ("Start loading:" + Www.url);
while (!www.isdone)
{
if (gamevar.gamestate = = Gamestate.jumping | | Gamevar.gamestate ==gamestate.jumpingasync)
loadscene.progress = www.progress;
Yield return 1;
}
if (www.error! = null)
Debug.logerror ("Loading error:" + Www.url + "\ n" +www.error);
Else
Debug.Log ("End loading:" + Www.url);
}
Public IEnumerator Loadwithtip (string resourcesname)
{
Debug.Log ("Start loading:" + Www.url);
LOADSCENE.TIPSTR = "Downloading resources<" + resourcesname + "> ...";
while (!www.isdone)
{
if (gamevar.gamestate = = Gamestate.jumping | | Gamevar.gamestate ==gamestate.jumpingasync)
Loadscene.progress= www.progress;
Yield return 1;
}
if (www.error! = null)
Debug.logerror ("Loading error:" + Www.url + "\ n" +www.error);
Else
Debug.Log ("End loading:" + Www.url);
}
}
Call:
Using Unityengine;
Using System.Collections;
Using System.Collections.Generic;
public class Loadresources:monobehaviour
{
static string url = "Http://61.149.211.88/Package/test.unity3d";
public static www www = null;
IEnumerator Start ()
{
if (! gamevar.resourcesloaded)
{
Gamevar.gamestate = gamestate.jumping;
Wwwobject obj = new Wwwobject (URL);
www = obj.www;
Yield return startcoroutine (obj. Loadwithtip ("textures"));
Gamevar.resourcesloaded = true;
Gamevar.gamestate = Gamestate.run;
}
}
}
Reference article:
http://game.ceeger.com/forum/read.php?tid=13148
http://www.zhihu.com/question/23895384
http://blog.csdn.net/tkokof1/article/details/11842673
http://blog.csdn.net/tkokof1/article/details/12834939
http://www.richardfine.co.uk/2012/10/unity3d-monobehaviour-lifecycle/
The Coroutine in Unity3d