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. windows 下安装nginx

    1.首先去官网下载 nginxWindows版本,官网下载:http://nginx.org/en/download.html 选择最新版本,下载到软件包后,解压文件包到指定目录,例如我的目录是D:\ ...

  2. [分享]4412开发板Android教程——Android开发环境搭建

    分享视频链接:http://pan.baidu.com/s/1o6tgEeQ 本文转载:www.topeetboard.com 下载和安装Android应用的开发环境 新建Android虚拟环境 An ...

  3. 如何去设计一个自适应的网页设计或HTMl5

    如何去设计一个自适应的网页设计或HTMl5 如今移动互联网随着3G的普及,越来越火爆,更多需求跟随而来!APP应用市场和APP应用数量成倍成倍的增长!从而给移动互联网带来新的挑战! 移动设备正超过桌面 ...

  4. MongoDB日志过大怎么办?

    MongoDB 日志文件过大怎么办? MongoDB的日志文件在设置 logappend=true 的情况下,会不断向同一日志文件追加的,时间长了,自然变得非常大. 解决如下:(特别注意:启动的时候必 ...

  5. 二分法 codevs 1432 总数统计

    codevs 1432 总数统计  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 给出n个数,统计两两之和小于k的方 ...

  6. HDU 5101 Select --离散化+树状数组

    题意:n 组,每组有一些值,求 在不同的两组中每组选一个使值的和大于k的方法数. 解法:n * Cnt[n] <= 1000*100 = 100000, 即最多10^5个人,所以枚举每个值x,求 ...

  7. UVA 12382 Grid of Lamps --贪心+优先队列

    题意:给出每行每列至少有的灯泡数,问最少有的灯泡数. 解法:要使灯泡数尽量小,说明要使交叉点尽量多,这样即抵了行,又抵了列,为最优的.所以可以用行来消去列,也可以用列来消去行,我这里是列来消去行.首先 ...

  8. 2014 UESTC 暑前集训队内赛(3) 部分解题报告

    B.Battle for Silver 定理:完全图Kn是平面图当且仅当顶点数n<=4. 枚举所有完全图K1,K2,K3,K4,找出最大总权重. 代码: #include <iostrea ...

  9. Unity3d+Jenkins 自动编译iOS、Android版本

    1.在Unity3d中, 创建导出 iOS.Android 项目脚本 PerformBuild.cs ,放在Editor目录下(必须),如下: using UnityEditor; using Sys ...

  10. WIN7系统自带截图工具SnippingTool

    在无网络的情况下,无QQ情况下,如何截图?以及如何设置快捷键? 方法 首先,我们在“开始”菜单最上面找到它,如图: 找不到也没关系 C:\Windows\system32\SnippingTool.e ...