Unity协程以及迭代器

来源:互联网 发布:科技美学知乎 编辑:程序博客网 时间:2024/06/07 01:54

早在写cocos-lua时就说要认真研究一下协程,然而…

参考
twisted oak
Edison
丘丘雷雷的博客
王选易
中辽普坦的专栏

IEnumerable

namespace System.Collection{public interface IEnumerable{    IEnumerator GetEnumerator();}}

任何继承了IEnumerable接口的都可以通过foreach来遍历。

IEnumerator

namespace System.Collection{public interface IEnumerator{    bool MoveNext();    object Current(get;);    void Reset();}}

.net官方关于IEnmerator的例子

public class PeopleEnum : IEnumerator{    public Person[] _people;    int position = -1;    public PeopleEnum(Person[] list){        _people = list;    }    public bool MoveNext(){        position++;        return (position < _people.Length);    }    object IEnumerator.Current{        get{return Current}    }    public Person Current{        get{            try{                return _people[position];            }catch(IndexOutOfRangeException ){                throw new InvalidOperationException();            }        }    }} 

Time slicing

不管什么时候,如果你想创建一个能够经历多个逻辑帧的流程,但是不适用多线程或多进程,那你就需要把一个任务来分割成多个任务,然后在下一帧继续执行这个任务。

斐波拉切

首先来一个经典的斐波拉切实现
[1,1,2,3,5,8…]

IEnumerator Fibonacci(){    int Fkm2 = 1;    int Fkm1 = 1;    yield return 1;     yield return 1;    while(Fkm1 + Fkm2 < int.MaxValue){        int Fk = Fk2 + Fk1;        Fk2 = Fk1;        Fk1 = Fk;        yield return Fk;    }}void Start(){    IEnumerator fib = Fibonacci();    for(i = 0 ; i < 10 ;i ++){        if(!fib.MoveNext()){            break;        }        Debug.Log((int)fib.Current);    }}

Unity协程

StartCoroutine

开启一个协程。协程的调用几乎没有任何性能开销,StartCoroutine一般都会以及返回,然而你也可以获得返回结果的值。但会等到协程结束才能生效。

StartCoroutine()生成一个Coroutine实例,第一次运行IEnumerator然后返回一个yielded值。
游戏逻辑在没帧执行。例如Update会在每帧调用,unity会在没帧调用保存的Coroutines并且处理IEnumerators返回的值。

yield return

  • 本质和return作用一样,将当前函数返回,只不过下次再调用这个函数是,会从yield return的下一句开始执行,函数本身的变量也都会一直保存上一次调用的状态,知道最后一次return,协程的状态才会被清除。

  • 一个协程可以在任何地方用yield暂停,yield return的值决定了什么时候恢复协程。

YieldInstruction

Yield return可以发挥任意YieldInstruction

  1. yield return null;暂停协同程序,下一帧再继续执行
  2. yield new WaitForFixedUpdate();暂停协同程序,等到下一次调用FixedUpdate方法时再继续往下执行
  3. yield return new WatiForSeconds(2);暂停协同程序,2秒后再继续往下执行
  4. yield return StartCoroutine(“SomeCortoutineMethod”)暂停此协同程序,开启SomeCortoutineMethod协同程序
  5. yield return WWW
    C#
    IEnumerator Start(string url){
    WWW www = new WWW(url);
    yield return www;
    ...
    }
YieldInstruction y;if(something){    y = null;}else if(something){    y = new WatiForEndOfFrame();}else{    y = new WaitForSeconds(1.0f);}yield return y;

协程嵌套

IEnumerator UntilTrueCoroutine(Func fn){    while(!fn()) yield return null; }Coroutine UntilTrue(Func fn){    return StartCoroutine(UntilTrueCoroutine(fn));}IEnumerator SomeTask(){    yield return UntilTrue(() => _lives < 3); }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婴儿几个月可以竖着抱 婴儿什么时候可以竖着抱 婴儿什么时候可以竖抱 新生儿几个月可以竖抱 宝宝三个月可以竖着抱吗 小孩几个月可以竖着抱 宝宝什么时候可以竖着抱 宝宝什么时候可以竖抱 孩子几个月可以竖着抱 小孩几个月可以竖抱 孩子几个月可以竖抱 宝宝几个月才能竖着抱 三个月的宝宝可以竖着抱吗 两个多月的宝宝可以竖着抱吗 宝宝什么时候能竖着抱 两个月的宝宝可以竖着抱吗 几个月的宝宝可以竖着抱 几个月婴儿可以竖着抱 婴儿三个月可以竖抱吗 2个月的宝宝可以竖着抱吗 小宝宝几个月可以竖着抱 婴儿两个月可以竖抱吗 婴幼儿几个月可以竖着抱 一个月的宝宝可以竖着抱吗 多大的婴儿可以竖着抱 二个月的宝宝可以竖着抱吗 几个月的宝宝可以竖抱 多大的宝宝可以竖着抱 3个月的宝宝可以竖着抱吗 新生儿多大可以竖着抱 宝宝两个月可以竖着抱吗 两个月宝宝喜欢竖着抱 三个月的婴儿可以竖着抱吗 2个多月的宝宝可以竖着抱吗 新生儿多久可以竖着抱 竖撇的字 一撇一竖是什么字 竖撇的写法图片 竖撇的写法 上面一个二下边一撇一竖 竖杠