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. IDEA成功注册方法

    IDEA成功注册方法 1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ ...

  2. spring 加载jar包中的配置文件

    package com.xxx.ssptsppt.dataexchange.utils; import com.xxx.maybee.engine.utils.FileUtil; import com ...

  3. FileZilla等软件搭建ftp服务器

    一.常用的几款ftp服务器软件介绍 1.1 Server-U Serv-U是一种被广泛运用的FTP服务器端软件,支持3x/9x/ME/NT/2K/2000/xp等全Windows系列.可以设定多个FT ...

  4. android 避免线程的重复创建(HandlerThread、线程池)

    最近在android开发中,用到都是new Thread(){...}.start()这种方式.本来这样是可以,但是最近突然爆出Performing stop of activity that is ...

  5. 【转】]Android实现开机自动运行程序

    有些时候,应用需要在开机时就自动运行,例如某个自动从网上更新内容的后台service.怎样实现开机自动运行的应用?在撰写本文时,联想到高焕堂先生以“Don't call me, I'll call y ...

  6. Axiom3D:Ogre动画基本流程与骨骼动画

    在Axiom中,Animation类用于管理动画,在此对象中主要管理着AnimationTrack对象,此对象用于管理动画的各种类型的每一桢.在Axiom中,动画类型主要有变形动画,姿态动画,骨骼动画 ...

  7. [转]浅谈Android五大布局(二)——RelativeLayout和TableLayout

    在浅谈Android五大布局(一)中已经描述了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoulteLayout(绝对布局)三种布局结构,剩下的两种布局Relati ...

  8. 记一些常用到的python中的函数

    1. zip()函数 它的作用是从参数中按顺序一一抽出子参数组出一个新的tuple.  直接看例子: >>> mean = np.array([2, 5, 4]) >>& ...

  9. Java如何获取正在运行的线程的名称?

    在Java编程中,如何获取正在运行的线程的名称? 以下示例显示如何获取正在运行的线程的名称. package com.yiibai; public class GettingThreadName ex ...

  10. (原)多线程sdl_ttf显示文字

    最近在使用sdl做视频显示,因为需要显示文字,所以就找了sdl的拓展库,sdl_ttf来做文字显示. 这里说明一下:sdl_ttf不支持多线程,官方上面有说明,它不是多线程安全的. 所以当我最初使用s ...