在程序开发时,光是了解协程怎么用是远远不够的,因为当程序出现一些有关于协程的错误时,理解协程的原理就十分有必要性了。
1.协程使用的一些问题
我们知道如果在Unity中编写一个死循环,会造成运行游戏时整个Unity编辑器卡死,而协程函数在使用时好像是可以与Update函数并行不斥的,那如果在一个协程函数里面编写一个死循环会怎么用呢?答案也是程序会卡死。
所以,我们知道了,协程函数并不是一个独立的执行单元,它与Update函数一样,被Unity依次执行。一旦有一个发生了死循环,游戏将会卡死。简而言之,协程不是线程。
从上面可以看到,协程非常像一个自定义的Update函数,只不过内部含有延时逻辑。而有意思的是,Mono的生命周期函数例如Start和Update是可以支持协程调用的,只是不需要使用StartCoroutine就可以直接调用。
public class Coroutine : MonoBehavior{ IEnumerator Start(){ Debug.log(1); yield return new WaitForSeconds(1); Debug.log(2); yield return new WaitForSeconds(1); } }
上述的Start方法并不是主动调用的,而是被Unity引擎识别并调用的,这里把Start的返回值void改成了IEnumerator,也同样被Unity识别了。
2.迭代器
虽然协程是Unity提供的,但是IEnumrator则是C#的语法,所以我们要弄清楚协程就先要知道这两个玩意的机制。事实上,IEnumrator与yield配合实现了一种叫做“可重入函数”的机制,也就是函数可以被打断一会,之后再执行的机制。
public class Itr:MonoBehaviour{ IEnumerator<int> HelloWorld(){ transform.position = new Vector3(1,0,0); yield return 233; transform.position = new Vector3(2,0,0); yeild return 666; } void Start(){ IEnumerator<int> e = HelloWorld(); while(){ if(!e.MoveNext()){ break; }else{ Debug.log("yield 返回值"+e.Current); Debug.log("当前位置"+transform.position); } } } }
这里HelloWorld就是一个可重入函数,在初次执行时会在第一个yield处卡住,返回值是一个IEnumrator对象,之后程序会把他保存在e变量中。每次调用e.MoveNext()方法时会让函数继续执行到下一个yield处,执行到最后一个yield后,函数彻底执行完毕,并且返回false;
每次执行一步,还可以从变量e中获取到中断时的返回值,即e.Current。这个返回值将非常有用。
yield在生命周期的运行时机:我们知道要使用协程的脚本必须先继承自MonoBehaviour。其中一个原因就是在协程的yield也在Mono生命周期中,且在Update与LatedUpdate之间。以下是常用的
yield return null; 暂停协程等待下一帧继续执行
yield return 0或其他数字; 暂停协程等待下一帧继续执行
yield return new WairForSeconds(时间); 等待规定时间后继续执行
yield return StartCoroutine("协程方法名");开启一个协程(嵌套协程)
yield return new WaitForFixedUpdate()
:等到下一个固定帧数更新
yield return new WaitForEndOfFrame()
:等到所有相机画面被渲染完毕后更新
3.协程的延时执行原理
IEnumerator<int> HelloWorld(){ float helloTime = 0; transform.position = new Vector3(1,0,0); helloTime = Time.time+1; while(Time.time<helloTime){ // 返回值没用 yield return 1; } }
上述代码中,Update函数每帧都会调用协程函数,而协程函数自身会用循环控制运行的进度,如果时间不到就立即中断,最终实现了定时运行的效果。这一实现方法从原理上与Unity中一致(Unity源码不开放)。
标签:return,函数,yield,Unity,详解,new,协程 From: https://www.cnblogs.com/CatSevenMillion/p/17554490.html