【Unity/笔记】协程Coroutine

本文介绍了Unity中的协程Coroutine,它不是进程或线程,而是通过yield return实现类似多线程并发执行的效果。协程可以被声明为IEnumerator类型的方法,并通过StartCoroutine开启,通过StopCoroutine结束。协程本质是迭代器,实现于IEnumerator和IEnumerable接口。文章详细阐述了协程的执行顺序、生命周期以及与其他语言中迭代器的相似性。

协程


介绍

  • 不是进程或线程,执行过程类似于子例程或者说不带返回值的函数调用。
  • 达到类似多线程的并发执行效果
  • 在yield return 处移交控制权。
  • 可以提前结束执行

使用

  • 声明方式
    1. IEnumerator [methodName] (){yield return XXX }
    2. IEnumerator [methodName] (){yield return T }
  • 开启方式

    1. public Coroutine StartCoroutine(IEnumerator methodName());
    2. public Coroutine StartCoroutine(string methodName);
    3. public Coroutine StartCoroutine(string methodName, [DefaultValue(“null”)] object value);

    StartCoroutine会立即执行开启传入的协程并返回一个Coroutine类型。

  • 结束方式

    1. public void StopCoroutine(IEnumerator methodName());
    2. public void StopCoroutine(string methodName);
    3. public void StopCoroutine(Coroutine routine);

      前两种结束方式根据参数类型分别对应开启方式的三种,第三种结束方式传入参数为StartCoroutine所返回的Coroutine类型实例。

      内部结束执行
      yield break;

  • 执行顺序:开启协程后会立即开始执行协程中的命令,直到遇到第一个yield return 时会暂时把控制权移交出去并继续执行其它代码,此时这个协程在这一帧中已经无法继续往下执行了,下一帧开始后根据生命周期函数的执行顺序去访问一次协程,如果可以则会从上次yield return的地方继续往下执行,以此类推。

    关于协程中各类yield return在一帧中执行的顺序可以查阅Unity目录下的Editor/Data/Documentation/en/Manual/ExecutionOrder.html的生命周期图,也可通过Unity内帮助进行访问。


协程本质

  • 协程的本质是迭代器,它们被封装在IEnumerator,IEnumerable以及他们俩的泛型形式IEnumerator,IEnumerable之中。其中IEnumerator还实现了IDisposable接口。

    public interface IEnumerator
    {
    object Current { get; }
    bool MoveNext();
    void Reset();
    }
    public interface IEnumerable
    {
    IEnumerator GetEnumerator();
    }
    public interface IEnumerator : IEnumerator, IDisposable
    {
    T Current { get; }
    }
    public interface IEnumerable : IEnumerable
    {
    IEnumerator GetEnumerator();
    }
    public interface IDisposable
    {
    void Dispose();
    }

  • IEnumerable 用来获取一个迭代器(IEnumerator),而迭代工作实际在IEnumerator中实现,这一过程可以通过代码来模拟完成。

    1. 执行一个协程IEnumerator,将返回得到一个新类型实例 ,循环执行该实例的MoveNext方法,如果MoveNext返回true则打印出该实例的属性Current,这样可以看到在协程中yield return的值都被依次打印出来,这就是foreach方法所执行的大概过程。
    2. IEnumerable提供了一个GetEnumerator的方法用来获取迭代器。
      3.协程中所返回的值被迭代器保存在堆上以便后面继续使用,每次调用MoveNext()方法时会从上次yield return的地方继续。
    3. 其实迭代器这种设计在多种主流语言中都可见到,如Java,ECMAScript,Python等,通常多使用于集合类数据结构的遍历。

迭代器是什么

  • 迭代器工作原理是使用状态机,在迭代器创建完一个新类型且一次未调用MoveNext前,状态机的状态为0(初始状态),
  • 此后在迭代器每次状态改变前的状态都会被重置为-1(预备状态/结束状态),
  • 然后执行过程中的代码并记录当前返回值,在一系列状态完成之后状态会依次变为1,2,3,4…(完成状态)以便记录所执行到的位置。
  • 另外,由于IEnumerable还需额外执行GetEnumerator方法来获取到IEnumerator,状态机用-2(转接状态)来标记这一阶段的状态

参考资料:

  1. 《使用C#语言开发跨平台游戏》—陈嘉栋
  2. Unity官方文档
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值