美文网首页
跟诸子学游戏 unity3d 协程

跟诸子学游戏 unity3d 协程

作者: 诸子百家谁的天下 | 来源:发表于2018-03-16 20:32 被阅读54次

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

    相关文章

      网友评论

          本文标题:跟诸子学游戏 unity3d 协程

          本文链接:https://www.haomeiwen.com/subject/ilirqftx.html