Unity中的Coroutine(协程)

估计熟悉Unity的人看过或者用过StartCoroutine()

假设我们在场景中有一个UGUI组件, Image:

将以下代码绑定到Image

 using UnityEngine;
using System.Collections;
using System.Threading;
using UnityEngine.UI; public class CoroutineDemo : MonoBehaviour { // Use this for initialization
void Start () { Debug.Log (Thread.CurrentThread.Name + ": Start begin. fCount=" + + Time.renderedFrameCount); this.StartCoroutine (exeuteCoroutine());
} // Update is called once per frame
void Update () { Debug.Log (Thread.CurrentThread.Name + ": Update(): fCount=" + Time.renderedFrameCount);
} public IEnumerator exeuteCoroutine(){
Debug.Log (Thread.CurrentThread.Name + ": Before yield return A, fCount=" + Time.renderedFrameCount);
//yield return new WaitForSeconds(1);
yield return "A";
// yield return "C";
// yield return "D";
Debug.LogError (Thread.CurrentThread.Name + ": After yield return A, fCount=" + Time.renderedFrameCount);
} IEnumerator LoadImage()
{
WWW www=new WWW("http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg");
Image img = this.gameObject.GetComponent<Image> (); Debug.Log("Before yield return: " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); yield return www; Debug.Log("After yield return, " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount);
Rect spriteRect = new Rect (, , www.texture.width, www.texture.height);
Sprite imageSprite = Sprite.Create (www.texture, spriteRect, new Vector2 (0.5f, 0.5f));
img.sprite = imageSprite; }
}

运行之后日志输出(Error 日志是为了明显,才这么打的):

fCount 代表的是当前已经渲染的帧数,发现, yield return 之后的代码, 是在yield return 之后的一帧执行的。

如果yield return 之后换成 new WaitForSeconds(1); yield之后的代码就在1秒后执行。

看一下MonoBehaviour的生命周期:

发现, 在StartCortinue()传入的方法中, 可以yield return 的类型有:

yield return null;

yield return WaitForSeconds(); (实际上, 继承自 YieldInstruction的都可以)

yield return WWW;

如果将例子中的代码改成加载图片:

     void Start () {
Debug.Log (Thread.CurrentThread.ManagedThreadId + ": Start begin. fCount=" + + Time.renderedFrameCount);
this.StartCoroutine (LoadImage());
}
     IEnumerator LoadImage()
{
WWW www=new WWW("http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg");
Image img = this.gameObject.GetComponent<Image> (); Debug.Log("Before yield return: " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); yield return www; Debug.Log("After yield return, " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount);
Rect spriteRect = new Rect (, , www.texture.width, www.texture.height);
Sprite imageSprite = Sprite.Create (www.texture, spriteRect, new Vector2 (0.5f, 0.5f));
img.sprite = imageSprite; }

通过输出日志, 你会发现, yield return www;之后的代码, 是在www.isDone之后, 也就是图片加载完毕之后才执行的!

Before yield return: http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg is done? False, rf=1
UnityEngine.Debug:Log(Object)
<LoadImage>c__Iterator6:MoveNext() (at Assets/Scripts/CoroutineDemo.cs:)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
CoroutineDemo:Start() (at Assets/Scripts/CoroutineDemo.cs:) After yield return, http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg is done? True, rf=34
UnityEngine.Debug:Log(Object)
<LoadImage>c__Iterator6:MoveNext() (at Assets/Scripts/CoroutineDemo.cs:)

总结:

yield return 搭配上WaitForSecond, WWW, 可以达到延时执行的效果。

但是, 特别注意的是, StartCoroutine()并没有开启新的线程来执行, 还是执行在与Start(), Update()相同的主线程中!

C#中的yield return与Unity中的Coroutine(协程)(下)的更多相关文章

  1. C#中的yield return与Unity中的Coroutine(协程)(上)

    C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...

  2. 可惜Java中没有yield return

    项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...

  3. C#中的yield return用法演示源码

    下边代码段是关于C#中的yield return用法演示的代码. using System;using System.Collections;using System.Collections.Gene ...

  4. Unity之"诡异"的协程

    为什么说是诡异的协程呢?首先从一个案例说起吧,示例如下: 游戏目标:让小车进入到对应颜色屋子里,即可获得一分.(转弯的道路可控)   为了让小车能够平滑转弯,小车的前进方向需要和车子的位置与圆心组成的 ...

  5. C#中的yield return

    4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的 ...

  6. unity, yield return new WaitForSeconds(waitTime) 在 Time.timeScale=0下卡死

    例如下面代码: IEnumerator f(){ Time.timeScale = 0; float waitTime=2; yield return new WaitForSeconds (wait ...

  7. Android中的Coroutine协程原理详解

    前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...

  8. Unity脚本编程之——协程(Coroutine)

    本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html 专有名词: Coroutine 协程 Alpha 不透明度 当你调用一个函 ...

  9. 【Unity笔记】使用协程(Coroutine)异步加载场景

    using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System; public ...

随机推荐

  1. p2p投资理财入门篇(新手必备)

    在互联网金融浪潮下,如果你只知道余额宝.理财通,如果你认为宝宝们就可以代表整个互联网金融,那可真是大错特错.这些年来,P2P这股强大势力一直在互联网金融领域兴风作浪,随着被高层正名.监管升级,P2P的 ...

  2. Python基础之函数等等

    三元运算 三元运算(三目运算),是对简单的条件语句的缩写. 1 2 3 4 5 # 书写格式   result = 值1 if 条件 else 值2   # 如果条件成立,那么将 "值1&q ...

  3. jenkins maven svn 部署web项目到本地Tomcat

    查了N多网页,折腾了几个小时,终于部署成功,部署的过程比较坎坷,遇到各种问题,记录一下,不管大家是否会遇到的同样的问题,希望有所帮助: 常规操作: 1.下载jenkins,必须要做的一步,http:/ ...

  4. 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点

    平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...

  5. Oracle 性能维护一点

    大数据量表的维护原则 1.如果此表经常CRUD,最好的办法是定期收集统计信息传递给oracle优化器,提高性能.例如dbms_stats.gather_table_stats命令. 可以做在ETL中, ...

  6. javaScript事件(四)event的公共成员(属性和方法)

    一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 四.IE事件处理程序 以上内容见javaScript事件(二)事件处理程序 五.事件对象 以上内容见javaS ...

  7. hihocoder-1391&&北京网赛09 Countries(优先队列)

    题目链接: Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, country ...

  8. codeforces 616E Sum of Remainders (数论,找规律)

    E. Sum of Remainders time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  9. UVALive 6181

    模拟题,注意细节.. #include <iostream> #include<stdio.h> #include<math.h> #include<stri ...

  10. SQL Server进制

    在项目中,大家可能都遇到过,需要把十进制转换为其他进制的情况,google上一搜,已经有很多2进制.8进制.16进制和十进制的转换方法.但是在一些项目中,这些可能无法满足要求,可能需要17.18甚至是 ...