跟诸子学游戏 unity3d 协程

在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:东西太多,无一一测试,如果错误,请指出,我所有的文章皆站在巨人的肩膀上写出.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 协程介绍 Unity的协程系统是基于C#的一个简单而强大的接口,IEnumerator,它允许你为自己的集合...
    壹米玖坤阅读 6,287评论 0 9
  • 为什么需要协程 在游戏中有许多过程(Process)需要花费多个逻辑帧去计算。 你会遇到“密集”的流程,比如说寻路...
    tmgg阅读 1,442评论 0 5
  • 第三篇 如何使人喜欢你 17. 学会真诚地关心他人 我的朋友朝阳转发的日志中有这样一段:心,退一步是宽容;眼,让一...
    禅园听雪阅读 755评论 5 15
  • 1、何为第一性原理 埃隆·马斯克不止一次的提到过,他之所以能够在多个领域取得成功,来自于他对「第一原理」(Firs...
    广逛阅读 1,240评论 0 0
  • 这些天一直在家陪爸妈,还有就是跟好基友约饭,不知不觉国庆长假就过完啦,放假前的一个重要规划也终于完成,那就是整理我...
    帝都三脚猫阅读 34,767评论 2 49