0x00 前言

在使用Unity的过程中,对协程仅仅知道怎样使用,但并不知道协程的内部机理,对于自己不清楚的部分就像一块大石压力心里。让自己感觉到担忧和不适。

这篇文章一探到底,彻底揭开协程的面纱,让大家在使用中不再有后顾之忧。

0x01 概念

协程是:程序组件来生成非抢占式多任务子函数,生成的子函数同意在程序里挂起和唤醒操作。

0x02 使用场景

通常协程能够非常方便实现延时操作。以及异步载入操作。以下是两个简单协程使用样例。

延时操作

// Use this for initialization
void Start () {
StartCoroutine (Wait ());
} IEnumerator Wait(){
Debug.Log ("start time:" + Time.time);
yield return new WaitForSeconds (1);
Debug.Log ("time:" + Time.time);
yield return new WaitForSeconds(2);
Debug.Log ("time:" + Time.time);
}

异步载入资源

// Use this for initialization
void Start () {;
System.Action<string> callBack = delegate(string text) {
Debug.Log(text);
};
StartCoroutine (LoadRes (callBack));
} IEnumerator LoadRes(System.Action<string> callBack){
WWW www = new WWW ("http://www.baidu.com");
yield return www; if (string.IsNullOrEmpty (www.error)) {
callBack(www.text);
Debug.Log("load success");
}
else{
Debug.Log("load failed");
}
}

0x03 原理

Unity里的协程通过定义一个返回 IEnumerator类型的函数。先来通过一个函数看看Unity都能返回那些类型:

IEnumerator Test(){
yield return 2; // 返回整数
yield return 4.2; // 返回浮点数
yield return null; // 返回null
yield return new WaitForSeconds(1); // 返回instance
yield return new WWW ("http://www.baidu.com"); // 返回instance
}

返回的类型有什么要求?整理一下Unity都实现了那些返回类型:

1、int类型,须要等待的帧数

2、float类型,须要等待的时间(秒)

3、null,等待一帧

4、break,结束协程

5、实例,必须有bool isDone()成员函数,等isDone返回true

6、IEnumerator,等IEnumerator实例的MoveNext()返回false

Unity的返回类型知道了,怎样捕获这些返回类型?来看IEnumerator怎样实现的?

public interface IEnumerator
{
//
// Properties
//
object Current
{
get;
} //
// Methods
//
bool MoveNext (); void Reset ();
}

通过研究IEnumerator接口,得到通过调用MoveNext。我们能够得到遍历全部yield返回的值,返回的值能够通过Current得到。每次调用MoveNext都会运行夹在yield中间的代码。

写个測试程序来验证我们的理论:

public class game_client : MonoBehaviour {

    // Use this for initialization
void Start () {
IEnumerator i = Test ();
while (true) {
if(!i.MoveNext()){
break;
}
object cur = i.Current;
if(cur != null)
Debug.Log(cur.GetType());
else
Debug.Log("type is null");
}
} IEnumerator Test(){
yield return 2;
yield return 4.2;
yield return null;
yield return new WaitForSeconds(1);
yield return new WWW ("http://www.baidu.com");
}
}

通过验证程序。能够得到yield返回的值。有了这些值,就能够实现自己的协程。

0x04 实现

设计接口:

class ScheduleCoroutine
{
public void StartCoroutine(IEnumerator coroutine);
public void StopCoroutine(IEnumerator coroutine);
public void Update(int frame, float time);
}

设计数据结构:

class CoroutineNode{
public IEnumerator itor;
public string name;
public int frame;
public float time;
public Object instance;
public CoroutineNode pre;
public CoroutineNode next;
}

详细实现代码,对于不同的项目需求,有不同的实现方式。这篇文章主要是探寻Unity协程的实现方式。

搞清楚原理后,在使用上就会更加得心应手。

0x05 參考

文章參考了非常多其它博文。感谢他们的付出。

在第一个參考链接里。有详细实现代码。

1、

title=CoroutineScheduler">UnifyWiki

2、维基百科

Unity 协程使用指南的更多相关文章

  1. Unity协程(Coroutine)管理类——TaskManager工具分享

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

  2. Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 其实协程并没有那么复杂,网上很多地方都说是多 ...

  3. Unity协程(Coroutine)原理深入剖析(转载)

    记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是怎么样的,只是知道函数的返回值是IEnumerator类型,函数中使用yield r ...

  4. unity协程coroutine浅析

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下 ...

  5. Unity协程Coroutine使用总结和一些坑

    原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...

  6. 深入浅出!从语义角度分析隐藏在Unity协程背后的原理

    Unity的协程使用起来比较方便,但是由于其封装和隐藏了太多细节,使其看起来比较神秘.比如协程是否是真正的异步执行?协程与线程到底是什么关系?本文将从语义角度来分析隐藏在协程背后的原理,并使用C++来 ...

  7. Unity协程(Coroutine)原理深入剖析再续

    Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine ...

  8. Unity协程使用经验

    [Unity协程使用经验] 1.协程的好处是,异步操作发起的地方和结束的地方可以统一在一个方法,这样就不用引入额外的成员变量来进行状态同步. 2.在一个协程中,StartCoroutine()和 yi ...

  9. 【转】Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网 ...

随机推荐

  1. hbase源码系列(十)HLog与日志恢复

    HLog概述 hbase在写入数据之前会先写入MemStore,成功了再写入HLog,当MemStore的数据丢失的时候,还可以用HLog的数据来进行恢复,下面先看看HLog的图. 旧版的HLog是实 ...

  2. Android训练课程(Android Training) - 高效的显示图片

    高效的显示图片(Displaying BitmapsEfficiently) 了解如何使用通用的技术来处理和读取位图对象,让您的用户界面(UI)组件是可响应的,并避免超过你的应用程序内存限制的方式.如 ...

  3. mssqlserver获取表说明和行数

    SELECT a.*,t.rows FROM ( ) ) AS a left join (, )) ) AS t ON a.表名=t.name

  4. CRNA的使用

    为了能让更多人感受 RN 的魅力,早在几个月前 React-community 就给出了一个不错的解决方案,可以让一个完全没接触过 RN 的人,从配环境开始5分钟实现 Hello Wolrd 的编写( ...

  5. CSS3圆角,阴影,透明

    CSS实现圆角,阴影,透明的方法很多,传统的方法都比较复杂,用CSS3就方便很多了,虽然现在各浏览器对CSS3的支持还不是很好,但不久的将来CSS3就会普及. 1.圆角 CSS3实现圆角有两种方法. ...

  6. Navdeep Jaitly

    中文名:耐迪普 杰特尼 早期: 印度科技大学 1994-1995 滑铁卢大学 1998-2000 博士: 多伦多大学 Hinton实验室 2008-2014 工作: 谷歌大脑 2014-2017 英伟 ...

  7. python公司内部语言规范与语言风格

    一.python语言规范 1.1导入 Tip: 仅对包和模块使用导入 定义: 模块间共享代码的重用机制. 优点: 命名空间管理约定十分简单.每个标识符的源都用一种一致的方式指示.x.obj 表示obj ...

  8. C++复合类型(结构体)

    其实c++的结构体可以理解为类似于python的字典,我个人理解, 但有区别 先看结构 #include <iostream> 关键字 标记成为新类型的名称 struct inflatab ...

  9. 【Python】windows电脑 python3.6安装lxml库

    1.下载lxml的wheel文件 https://download.lfd.uci.edu/pythonlibs/t5yhk4lc/lxml-4.2.1-cp36-cp36m-win32.whl 其他 ...

  10. 推荐一个不错的关于Excel数据统计分析的公众号