U3D协程yield的使用和理解
部分内容参考网址:http://blog.csdn.net/huang9012/article/details/29595747
Win7+U3D 4.6.7
1.在c#中使用
①首选需要定义一个返回值为IEnumerator的协程函数
IEnumerator Do(){
Debug.Log("Do 1"); yield return ; //下面的代码延时到下一帧的update之后 Debug.Log("Do 2");
}
②使用StartCoroutine函数调用协程函数
void Start () {
Debug.Log("Start 1");
StartCoroutine(Do()); //调用协程函数
Debug.Log("Start 2");
}
③在Update函数中输出数字,判断Updata函数和协程之间的执行先后顺序
int i = ;
void Update () {
++i;
Debug.Log("Update " +i); //这里记录了调用update函数多少次
}
④在LateUpdate函数中输出数字,判断LateUpdate函数和协程之间的执行先后顺序
int j = ;
void LateUpdate()
{
++j;
Debug.Log("LateUpdate " + j); //这里记录了调用update函数多少次
}
⑤运行的输出顺序结果是:
Start
Do //yield之后再下一帧的update之后继续执行
Start
Update //第一帧(当前帧)update执行完
LateUpdate //第一帧(当前帧)的最后执行
Update //第二帧(下一帧执行)update执行完
Do //执行yield之后的代码
LateUpdate //没错,LateUpdate在协程之后
Update
LateUpdate
Update
LateUpdate
Update
LateUpdate …
2.关于协程的理解:
①在传统实时游戏中,在update中要延迟执行一些代码,或者满足一定条件后执行一些代码。需要在update添加一个计时器,用当前时间来减去前面记录的时间来判断执行。当这种情况越来越多的时候,会添加很多变量和代码,代码就越来越乱,这时候一般会抽象一个框架出来处理这个问题。协程就是解决这种问题的框架,换句话说yield return 0(return的是int值,任何值都一样,没有区别)的作用,就是在调用yield那行代码后(在yield函数处做一个记录标签),然后跳出协程函数继续执行外部的代码,在下一帧(是下一帧!)的update函数之后,根据yield函数的记录标签位置继续执行协程函数的后面部分代码。
②
yield return int是等待下一帧(应用场景:倒计时,分数累加,血条慢慢减少等)
yield return new new WaitForSeconds (2)是等待时间到
yield return new WWW(“http://chevin.net”)是等到页面响应
③协程和Update()一样更新,自然可以使用Time.deltaTime了,而且这个Time.deltaTime和在Update()当中使用是一样的效果(使用yield return int的情况下)
④协程并不是多线程,它和Update()一样是在主线程中执行的,所以不需要处理线程的同步与互斥问题
⑤yield return null其实没什么神奇的,只是unity3d封装以后,这个协程在下一帧就被自动调用了
3.为了更清楚的说明yield return int的下一帧执行的用处,分别使用两种方法实现同一个延时功能。
①使用update不断累加时间
using UnityEngine;
using System.Collections; public class dialog_easy : MonoBehaviour {
public string dialogStr = "一个一个字显示";
public float speed = 5.0f; private float timeSum = 0.0f;
private bool isShowing = false;
// Use this for initialization
void Start () {
ShowDialog();
} // Update is called once per frame
void Update () {
if(isShowing){
timeSum += speed * Time.deltaTime;
guiText.text = dialogStr.Substring(, System.Convert.ToInt32(timeSum)); if(guiText.text.Length == dialogStr.Length)
isShowing = false;
}
} void ShowDialog(){
isShowing = true;
timeSum = 0.0f;
}
}
②使用yield return int每帧自动调用(明显这种用法简洁明了得多)
using UnityEngine;
using System.Collections; public class dialog_yield : MonoBehaviour {
public string dialogStr = "一个一个字显示";
public float speed = 5.0f; // Use this for initialization
void Start () {
StartCoroutine(ShowDialog());
} // Update is called once per frame
void Update () {
} IEnumerator ShowDialog(){
float timeSum = 0.0f;
while(guiText.text.Length < dialogStr.Length){
timeSum += speed * Time.deltaTime;
guiText.text = dialogStr.Substring(, System.Convert.ToInt32(timeSum));
yield return null;
}
}
}
U3D协程yield的使用和理解的更多相关文章
- Unity3D协程yield的理解
Unity3D的协程概括地将就是:对于一段程序,你可以加上yield标明哪里需要暂停,然后在下一帧或者一段时间后,系统会继续执行这段代码.协程的作用:①延迟一段时间执行代码.②等某个操作完成之后再执行 ...
- tornado 协程的实现原理个人理解;
tornado实现协程的原理主要是利用了(1)python里面的generator (2)future类和ioloop相互配合,两者之间的相互配合是通过gen.coroutine装饰器来实现的: 具体 ...
- python协程--yield和yield from
字典为动词“to yield”给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 next(...) 的 ...
- python协程(yield、asyncio标准库、gevent第三方)、异步的实现
引言 同步:不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的. 例如购物系统中更新商品库存,需要用"行锁"作为通信信号,让不同的更新 ...
- U3D协程Coroutine之WWW与Update()的并行测试
using System.Collections; using UnityEditor; using UnityEngine; using UnityEngine.UI; /************* ...
- (并发编程)进程池线程池--提交任务2种方式+(异步回调)、协程--yield关键字 greenlet ,gevent模块
一:进程池与线程池(同步,异步+回调函数)先造个池子,然后放任务为什么要用“池”:池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务池子内什么时候装进程:并发的任务 ...
- 多任务3(协程)--yield完成多任务交替执行
协程是并发,单线程,一次执行一个 来回切换 代码: import time def task_1(): while True: print("-----1-----") time. ...
- 协程,yield,i多路复用,复习
课程回顾: 线程池 队列:同一进程内的队列 先进先出 后进先出 优先级队列 线程池中的回调函数是谁在调用? 线程池中的回调函数是子线程调用的,和父线程没有关系 进程池中的会点函数是父进程调用的,和子进 ...
- 深入理解协程(二):yield from实现异步协程
原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的第二篇. yield from ...
随机推荐
- minicom的安装和tftp的安装
1.minicom 的安装 在弹出的窗口中选择“Serial port setup”进行配置.配置完之后选择“Save setup as dfl”保存.最后选择“Exit from Minicom”退 ...
- 持续集成之三:Maven私服Nexus使用
环境 Red Hat Enterprise Linux Server release 7.3 (Maipo) jdk1.7.0_80 apache-tomcat-7.0.90 mysql-5.7.23 ...
- Python中*args和**kwargs的区别
(注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正.) 中秋的夜,微凉,但却始终看不见月亮. 我想,它一定是害羞了,悄悄的躲到了乌云的后面. 嗯,就是这样,我真是太TM机智了. 正 ...
- mybatis项目启动报错 The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collection*,discriminator?)".
启动项目报错 2018-02-26 17:09:51,535 ERROR [org.springframework.web.context.ContextLoader] - Context initi ...
- 推荐:Java性能优化系列集锦
Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...
- 手撕vue-cli配置——webpack.base.conf.js篇
在开始写webpack.base.conf.js(简称base)之前,我们先来看一下vue-loader.conf.js这个文件,毕竟在base中我们还会用到: 'use strict' //引入前一 ...
- MySQL Crash Course #14# Chapter 22. Using Views
索引 视图是啥 为什么需要视图 使用视图的规则 如何使用视图 视图应用实例 别用视图更新数据! 视图是啥 理解视图的最佳方式就是看下面这个例子. SELECT cust_name, cust_cont ...
- ELK学习笔记之ELK分析nginx日志
0x00 配置FIlebeat搜集syslog #安装 rpm -ivh filebeat-6.2.3-x86_64.rpm mv /etc/filebeat/filebeat.yml /etc/fi ...
- Linux系统对IO端口和IO内存的管理
引用:http://blog.csdn.net/ce123_zhouwei/article/details/7204458 一.I/O端口 端口(port)是接口电路中能被CPU直接访问的寄存器的地址 ...
- 20145106 java实验二
1)复数类ComplexNumber的属性 m_dRealPart: 实部,代表复数的实数部分 m_dImaginPart: 虚部,代表复数的虚数部分 public class ComplexNumb ...