C#中的yield return与Unity中的Coroutine(协程)(下)
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(协程)(下)的更多相关文章
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...
- 可惜Java中没有yield return
项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...
- C#中的yield return用法演示源码
下边代码段是关于C#中的yield return用法演示的代码. using System;using System.Collections;using System.Collections.Gene ...
- Unity之"诡异"的协程
为什么说是诡异的协程呢?首先从一个案例说起吧,示例如下: 游戏目标:让小车进入到对应颜色屋子里,即可获得一分.(转弯的道路可控) 为了让小车能够平滑转弯,小车的前进方向需要和车子的位置与圆心组成的 ...
- C#中的yield return
4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的 ...
- unity, yield return new WaitForSeconds(waitTime) 在 Time.timeScale=0下卡死
例如下面代码: IEnumerator f(){ Time.timeScale = 0; float waitTime=2; yield return new WaitForSeconds (wait ...
- Android中的Coroutine协程原理详解
前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...
- Unity脚本编程之——协程(Coroutine)
本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html 专有名词: Coroutine 协程 Alpha 不透明度 当你调用一个函 ...
- 【Unity笔记】使用协程(Coroutine)异步加载场景
using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System; public ...
随机推荐
- javascript 特效实现(2)——回到顶部效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- (转载)Javascript定义类(class)的三种方法
因在公司内部培训中有讲解到JS类的概念,不甚明白,于是进行了google找到了相关的介绍说明,现将其摘抄下来,以作记录. 在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对 ...
- HTML5 datalist 标签
以前需要用JS写一个自动完成组件(Suggest),很费劲.HTML5时代则不用了,直接使用datalist标签,直接减少了工作量.如下 <!DOCTYPE html> <html& ...
- 查看Linux服务器内存使用情况
一个服务器,最重要的资源之一就是内存,内存够不够用,是直接关系到系统性能的关键所在. 本文介绍如何查看Linux服务器内存使用情况, 1.free命令 free -m [root@localhost ...
- virtualbox 在window10上的兼容性调整
更新完windows10后,打开当时的virtualbox 4.3.3已经是最新的啦,打开原来安装的几个虚拟机(hadoop),发现均失败. 打开setting一看,网络一栏有问题,桥接模式的虚拟机都 ...
- python Quicksort demo
__author__ = 'student' ''' quicksort step 1, choose one pivot, such as pivot=la[0] step 2, scan the ...
- Varchar2 size how to decide?
When you execute a complicate store procedure, maybe it will execute a long time, maybe you want to ...
- UVA-10269 (floyd+dijkstra)
题意: 现在有A个村庄,B个城堡,现在要从1到A+B,有M条路,魔法鞋最多能用K次,每次的长度不超过L,且起点和终点一定是村庄和城堡,而且每次使用魔法鞋不能穿过城堡,问最短时间是多少; 思路: 先用F ...
- (已解决) 未能加载文件或程序集“Newtonsoft.Json, Version=4.0.0.0, Culture=neutral,
在项目web.config里面添加: <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30AD4F ...
- String类详解(1)
首先String是一个类. 1,实例化String类方法. 1)直接赋值:String name="haha"; 2)通过关键字:String name=new String(&q ...