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 ...
随机推荐
- proxool详细配置
proxool详细配置 博客分类: Java 配置管理SQLServletprototypeXML proxool一个数据库连接池框架,提供了对你选择的其它类型的驱动程序的连接池封装.可以非常简单的 ...
- web.xml文件报错:The processing instruction target matching "[xX][mM][lL]" is not allowed.
昨晚把我的项目上传到了gitlab,然后今天在公司从gitlab下载下来, 发现web.xml报错.
- 21 数据库编程 - 《Python 核心编程》
- MSBI BigData demo—sqoop import
--sp_readerrorlog 读取错误的信息记录 exec sys.sp_readerrorlog 0, 1, 'listening'查看端口号 首先hadoop环境要配置完毕,并检验可以正常启 ...
- Vim tips
1.光标移动: (1).NG -> 移动到第N行,或者使用:N (2).gg -> 移动到第一行 (3).G -> 移动到最后一行 (4).单词移动: w -> 移动到下一个单 ...
- 怎样绘制ZBrush中的纹理
利用ZBrush的内置插件“投影大师”和“Polypainting”纹理贴图能够快速实现纹理的绘制.本文将对这两种方法的应用流程做一个介绍. 查看跟多内容请直接前往:http://www.zbrush ...
- UVA 11766 Racing Car Computer --DP
题意:电脑记录了某一时刻每个赛车的前面和后面个有多少辆车(多个车并排时在别的车那只算一辆),问最少有多少个不合理的数据. 分析:看到n<=1000时,就尽量往DP上想吧. 每输入一组数据a,b, ...
- 2014 Super Training #7 E Calculate the Function --矩阵+线段树
原题:ZOJ 3772 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3772 这题算是长见识了,还从没坐过矩阵+线段树的题 ...
- 三维网格形变算法(Linear rotation-invariant coordinates和As-Rigid-As-Possible)
在三维网格形变算法中,个人比较喜欢下面两个算法,算法的效果都比较不错, 不同的是文章[Lipman et al. 2005]算法对控制点平移不太敏感.下面分别介绍这两个算法: 文章[Lipman et ...
- tomcat7 - 烫手山芋之热部署
tomcat7部署,项目发布有很多种方式 1. 增量发布,把修改过得那些文件手动上传至tomcat,*.class *.xml 等等,这样的缺点非常大,需要断开tomcat,记住那些你修改过得文件,很 ...