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 ...
随机推荐
- 烂泥:centos安装及配置DHCP服务器
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 有关DHCP服务器的配置一直打算学习,这几天终于抽出时间来专门学习这个知识点. DHCP:动态主机配置协议,在此就不多做介绍.不清楚的童鞋,可以去百度下 ...
- 烂泥:KVM快照的创建与恢复
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 因为要做有关KVM虚拟机的实验,所以需要虚拟机生成快照.查询相关资料,说KVM可以使用两种方法生成虚拟机的快照. 方法一.使用qemu-img snap ...
- mysql管理(一)
创建数据库,并指定默认字符集和排序规则:help create database;create {database|schema} [if not exists] db_name [character ...
- linux内核编译,配置本机驱动
1.前言 编译linux内核失败的原因很多时候就是驱动选错,适合自己本机的驱动没编译进去.面对特殊平台(或者有些洁癖者,我就是^_^),要编译精简内核,只要本机驱动,其他都不需要.面对内核里面这么多 ...
- sigemptyset,sigfillset,sigaddset,sigdelset,sigismember,sigprocmask,sigpendmask作用
SYNOPSIS #include <signal.h> int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); in ...
- HttpURLConnection发送POST请求(可包含文件)
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io. ...
- [转]Javascript中的自执行函数表达式
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
- Verilog (一) assignment, register and net
Verilog 区分大小写, 且所有关键字都是小写 1 register = storage keyword reg; default x; variable that can hold value ...
- jsp 微信公众平台 token验证(php、jsp)(转载)
微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是PHP语言写的,很多地方操作起来让本人这个对java比较熟悉的小伙很别扭,所以仿照PHP的接口代码做了一套jsp语言编写的接口. 首先先把 ...
- grunt的使用方法,环境配置和插件安装
虽然现在grunt的用的越来越少了,但是插件数量还是相当多的,另外grunt和gulp的使用相当相似: grunt需要安装node和npm 验证node是否安装:node -v 验证npm是否安装:n ...