在unity中方法一般是在一帧之内执行完毕的,当方法耗时的时候,会产生帧率下降的情况.
Unity中的协程:
1:一个分部执行,遇到条件(yield return 语句)会挂起,直到条件满足才会被唤醒继续执行后面的代码。
2:Unity在每一帧(Frame)都会去处理对象上的协程。Unity主要是在LateUpdate()后去处理协程(检查协程的条件是否满足),相当于update函数加上代码执行位置,上下文环境.
3:Unity在每帧做的工作就是:调用 协程(迭代器)MoveNext() 方法,如果返回 true ,就从当前位置继续往下执行。
4:采用分帧概念执行,比如一个方法需要100W帧才能执行完毕,用了协程之后可以将其扩展到200W帧执行,并不影响主线程.
使用StartCoroutine()函数来调用协程函数
1: public Coroutine StartCoroutine(IEnumerator routine);
2:public Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value);
3: public Coroutine StartCoroutine(string methodName);
4: public Coroutine StartCoroutine_Auto(IEnumerator routine);
结束方法:
public void StopAllCoroutines();
public void StopCoroutine(string methodName);
public void StopCoroutine(IEnumerator routine)
public void StopCoroutine(Coroutine routine);
通过yield这个特殊的属性可以在任何位置、任意时刻暂停,也可以在指定的时间或事件后继续执行,而不影响上一次执行的就结果.例子:
例子协程并不会在Unity中开辟新的线程来执行,其执行仍然发生在主线程中。当我们有较为耗时的操作时,可以将该操作分散到几帧或者几秒内完成,而不用在一帧内等这个操作完成后再执行其他操作。例子:
打印1 例子1 打印2 例子2协程在实现过程中我们需要注意yield调用的时机,执行较为复杂的计算时,如果在时间上没有严格的先后顺序,我们可以每帧执行一次循环来完成计算,或者每帧执行指定次数的循环来防止在程序运行中出现的卡顿现象。
比如在for循环中 用一个if(i%2==0){yield return null;}进行每帧执行2次for循环.
yield return null/0; // 下一帧再执行后续代码
yield return 任意数字;// 任意数字 帧后 再执行后续代码
yield break; //直接结束该协程的后续操作
yield return asyncOperation;//等异步操作结束后再执行后续代码
yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码
yield return WWW();//等待WWW操作完成后再执行后续代码
yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码
yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10);
yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10);
yield 概念解析 :当你“yield”一个方法时,你相当于说了,“现在停止这个方法,然后在下一帧(或者 看return后面的条件)中从这里重新开始!”
IEnumerator方法 的返回值 表示这个方法的状态,StartCoroutine需要记录,然后进行调用.
注意:
1:当某一个脚本中的协程在执行过程中,如果我们将该脚本的enable设置为false,协程不会停止。只有将挂载该脚本的物体设置为SetActive(false)时才会停止,或者销毁该物体。
2:Coroutine co = StartCoroutine(...)的返回值co 在没有yield return返回时,co为null,不能使用.
3:StopAllCoroutines()方法表示停止这个物体上这个类的协程全部停止,其他物体上的类的协程不停止.
4:协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题. 延时(等待一段时间)执行代码,等待某个操作执行完成之后(比如一帧之后),再执行后面的代码.
5:协程是每帧的LateUpdate()后去运行,在start update LateUpdate方法中都调用一个协程,前后都打印log日志,yield return null 等测试.
6:一个空的/最简单的协程,也至少要执行2帧 例子:IEnumerator work(){yield return null};启动一次,也要执行至少2帧.
7:一个MONO中开启多个协程时,产生的调用顺序
start方法里面开启 Text1()/ Text2()/ Text3()类似结果:
第一次运行 随后的调用顺序 协程PS:东西太多,无一一测试,如果错误,请指出,我所有的文章皆站在巨人的肩膀上写出.
网友评论