http://blog.csdn.net/nizihabi/article/details/47606887

一、Coroutine(协程)的概念和本质

在网上的一些资料当中,一直将Coroutine当作一个线程来描述,这样是不准确的。因为Coroutine并不是一个新的线程,它仍旧是属于主线程的一部分。Coroutine本质上是一种轻量级的thread,它的开销会比使用thread少很多。多个Coroutine可以按照次序在一个thread里面执行,一个Coroutine如果处于block状态,可以交出执行权,让其他的Coroutine继续执行。

而在Unity当中,Coroutine是在所有的Update函数执行完成之后才开始执行的,也就是在LateUpdate()之后执行,主要是用来协助主线程进行工作,就像手动添加了一个另外的update()函数在里面一样,一般情况下我们用于延时触发的功能。下面是关于MonoBehavior的执行顺序图,可以看到Coroutine是在LateUpdate之后的。

而我们注意到上图中,Coroutine左边标注着几个yield模块,这个就是我们下面要讲的如何使用Coroutine里的内容了。

二、Coroutine的使用

在Untiy里面,如果想要将一个函数Fun作为一个Coroutine使用,有两点是需要注意的
1、Fun的返回类型要为IEnumerator
2、yield的使用
 
yield ,在Coroutine里面更像是一个红绿灯的作用,在满足紧跟在它后面的条件之前,这个协程会挂起,把执行权交给调用它的父函数,满足条件时就可以执行yield下面的代码。大家可以执行一下下面的代码看看效果
  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour
  4. {
  5. IEnumerator WaitAndPrint()
  6. {
  7. // suspend execution for 5 seconds
  8. yield return new WaitForSeconds(5);
  9. print("WaitAndPrint " + Time.time);
  10. }
  11. IEnumerator Start()
  12. {
  13. print("Starting " + Time.time);
  14. // Start function WaitAndPrint as a coroutine
  15. yield return StartCoroutine("WaitAndPrint");
  16. print("Done " + Time.time);
  17. }
  18. }

大家应该能得到下面的输出(本人的Unity版本是5.0.1f1)

另外大家可以再执行一下下面的代码,可以观察一下看看跟上面的有何异同
  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour
  4. {
  5. IEnumerator WaitAndPrint()
  6. {
  7. // suspend execution for 5 seconds
  8. yield return new WaitForSeconds(5);
  9. print("WaitAndPrint " + Time.time);
  10. }
  11. void Start()
  12. {
  13. print("Starting " + Time.time);
  14. // Start function WaitAndPrint as a coroutine
  15. StartCoroutine("WaitAndPrint");
  16. print("Done " + Time.time);
  17. }
  18. }

得到的输出如下:

从上面可以看到,我们是通过StarCoroutine的方法来启动一个新的Coroutine的,在第一段代码当中,把Start方法也声明成一个IEnumerator类型的时候,当执行到yield 模块,就会进行阻塞,等待yield模块完成了之后再继续往下执行,而声名成普通类型的时候,当启动了新的Coroutine的时候,遇到yield了,并不会把整个Start阻塞,而是会记录下当前执行的位置,然后返回父函数中执行,每一帧过后会检测yield是否满足,当满足yield条件,则返回到yield后面执行。
 
在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启一个线程。区别在于使用字符串作为参数可以开启线程并在线程结束前终止线程,相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串作为参数时,开启线程时最多只能传递一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。
 

在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序

还有一种终止Coroutine的方法,将gameObject的active属性设为False,但是设回true的时候并不会启动Coroutine。

注意:将Coroutine所在的脚本设为enable = false并不能够将Coroutine停止,因为它跟Monobehavior是同层级的。

Unity3D中的Coroutine及其使用(延时、定时调用函数)的更多相关文章

  1. Unity3D中的Coroutine详解

    Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutin ...

  2. Unity3D中的Coroutine具体解释

    本文太乱,推荐frankjfwang的:全面解析Coroutine技术 Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这种代码. 疑问: yie ...

  3. 【Unity3D/C#】Unity3D中的Coroutine详解

    Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutin ...

  4. Javascript中的定时调用函数setInterval()和setTimeout()

    首先介绍这两个函数 一.setInterval() 按照指定的周期来调用函数或表达式,执行多次.(时间单位:ms) timer = setInterval("content =documen ...

  5. JavaScript定时调用函数(SetInterval与setTimeout)

    setTimeout和setInterval的语法同样.它们都有两个參数.一个是将要运行的代码字符串.另一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将运行那段代码. 只是这两个函数还是有差别的 ...

  6. 怎样理解在函数中声明var x = y = 1后调用函数时, x是局部变量, y是全局变量

    下面这段代码在执行的时候, 打印的结果是1, Error: undefined; function fn() { var x = y = 1; } fn(); console.log(y); // 1 ...

  7. 【吐血推荐】简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候很容易看到下面这个例子: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yield ...

  8. 【Unity3D】简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候很容易看到下面这个例子: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yield ...

  9. 【转】简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Destroy ...

随机推荐

  1. html 自动跳转,meat(http-equiv)标签详解

    http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...

  2. jquery 与javascript关系 ①取元素 ②操作内容 ③操作属性 ④操作 样式 ⑤ 事件 点击变色

    jQuery的min版本和原版功能是一样的,min版主要应用于已经开发成的网页中,而非min版 的文件比较大,里面有整洁的代码书写规范和注释,主要应用于脚本开发过程当中. JQuery是继protot ...

  3. hdu4063(圆与圆交+线段与圆交+最短路)

    写几何题总是提心吊胆.精度问题真心吓人. 其实思路挺简单的一道题,真是什么算法和几何double搞到一块,心里就虚虚的. 思路:求出所有圆之间的交点,然后用这些交点跑一遍最短路就可以了. Aircra ...

  4. 反射机制,jvm,class类型

    [说明]这是上午完成的内容或者说是接触到的知识点,包括servlet简单的数据库连接,表格的显示需要用到的插件jstl,还有最最多的java反射原理的讲解 1)数据库的设计 2)编程中用到的知识点 3 ...

  5. CMD命令获取电脑所有连接过的WiFi密码

    cmd中输入命令:for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do  @echo ...

  6. SpringBoot中的配置文件

    http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

  7. thinkphp5, 省略index.php

    Apache:1. httpd.conf配置文件中加载了mod_rewrite.so模块2. AllowOverride None 将None改为 All3. 把下面的内容保存为.htaccess文件 ...

  8. Android笔记之GridView

    完整Demo链接:https://pan.baidu.com/s/1d_G9aCwBxpiYQcdQhwSDDw,提取码:5deh 效果图 activity_main.xml <?xml ver ...

  9. 浅谈公平组合游戏IGC

    浅谈公平组合游戏IGC IGC简介 一个游戏满足以下条件时被叫做IGC游戏 (前面三个字是自己YY的,不必在意) 竞争性:两名玩家交替行动. 公平性:游戏进程的任意时刻,可以执行的操作和操作者本人无关 ...

  10. 使用 Node.js 对文本内容分词和关键词抽取

    npm install nodejieba var nodejieba = require("nodejieba"); var result = nodejieba.cut(&qu ...