当前位置: 首页 > 编程日记 > 正文

yield学习续:yield return迭代块在Unity3D中的应用——协程

必读好文推荐:

Unity协程(Coroutine)原理深入剖析

Unity协程(Coroutine)原理深入剖析再续

上面的文章说得太透彻,所以这里就记一下自己的学习笔记了。

首先要说明的是,协程并不是线程,协程是运行在主线程中的,是和主线程同步执行的代码,不同的地方是运行的方法可以被yield return在当前帧进行打断,到下一帧后可以继续从被打断的地方继续运行。

下面我们看一个示例,场景中有一个空的GameObject对象,其绑定了下面的脚本:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Test : MonoBehaviour
 5 {
 6     int frame = 0;
 7 
 8     void Start ()
 9     {
10         this.StartCoroutine(CountDown());
11     }
12     
13     void Update ()
14     {
15         Debug.Log("Now is frame: " + (++frame));
16     }
17 
18     IEnumerator CountDown()
19     {
20         Debug.Log("step - 1");
21         yield return null;
22         Debug.Log("step - 2");
23         yield return null;
24         Debug.Log("step - 3");
25         yield return null;
26         Debug.Log("step - 4");
27     }
28 }

下面是执行的结果:

下面我们看看运行的逻辑是如何的:

当进入Start方法时开始启动协程,这时候协程开始运行,输出“step1”后遇到第一个yield return后暂停本帧的运行,接下来进入Update方法输出“frame1”,由于协程调用是在Update之后,所以第二帧开始后,先执行了第二个Update输出“frame2”,然后从协程的上次暂停处继续执行,输出“step2”后遇到第二个yield return后暂停本帧的运行,如此反复,当输出“step4”后发现方法已经执行完毕,协程结束。

下面看看yield break的效果,这个语句会立即中断协程的运行,代码如下:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Test : MonoBehaviour
 5 {
 6     int frame = 0;
 7 
 8     void Start ()
 9     {
10         this.StartCoroutine(CountDown());
11     }
12     
13     void Update ()
14     {
15         Debug.Log("Now is frame: " + (++frame));
16     }
17 
18     IEnumerator CountDown()
19     {
20         Debug.Log("step - 1");
21         yield return null;
22         Debug.Log("step - 2");
23         yield return null;
24         Debug.Log("step - 3");
25         yield break;
26         Debug.Log("step - 4");
27     }
28 }

下面是运行的结果:

我们可以发现“step4”已经运行不到了。

yield的返回值,我们可以返回null或者数字0,效果是一致的,同时还可以返回3个对象,分别如下:

yield return new WaitForFixedUpdate();

·等待直到下一个固定帧速率更新函数。

yield return new WaitForEndOfFrame();

·等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前。

yield return new WaitForSeconds(1);

·在给定的秒数内,暂停协同程序的执行。

下面我们来看一个例子,修改第一个例子的Test.cs:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Test : MonoBehaviour
 5 {
 6     int frame1 = 0;
 7     int frame2 = 0;
 8     int frame3 = 0;
 9 
10     void Start ()
11     {
12         this.StartCoroutine(CountDown());
13         this.StartCoroutine(CountDown_WaitForFixedUpdate());
14         this.StartCoroutine(CountDown_WaitForEndOfFrame());
15         this.StartCoroutine(CountDown_WaitForSeconds());
16     }
17     
18     void Update ()
19     {
20         Debug.Log("Update is frame: " + (++frame1));
21     }
22 
23     void FixedUpdate ()
24     {
25         Debug.Log("FixedUpdate is frame: " + (++frame2));
26     }
27 
28     void LateUpdate ()
29     {
30         Debug.Log("LateUpdate is frame: " + (++frame3));
31     }
32 
33     IEnumerator CountDown()
34     {
35         Debug.Log("yield - step - 1");
36         yield return null;
37         Debug.Log("yield - step - 2");
38         yield return null;
39         Debug.Log("yield - step - 3");
40     }
41 
42     IEnumerator CountDown_WaitForFixedUpdate()
43     {
44         Debug.Log("yield WaitForFixedUpdate - step - 1");
45         yield return new WaitForFixedUpdate();
46         Debug.Log("yield WaitForFixedUpdate - step - 2");
47         yield return new WaitForFixedUpdate();
48         Debug.Log("yield WaitForFixedUpdate - step - 3");
49     }
50 
51     IEnumerator CountDown_WaitForEndOfFrame()
52     {
53         Debug.Log("yield WaitForEndOfFrame - step - 1");
54         yield return new WaitForEndOfFrame();
55         Debug.Log("yield WaitForEndOfFrame - step - 2");
56         yield return new WaitForEndOfFrame();
57         Debug.Log("yield WaitForEndOfFrame - step - 3");
58     }
59 
60     IEnumerator CountDown_WaitForSeconds()
61     {
62         Debug.Log("yield WaitForSeconds - step - 1");
63         yield return new WaitForSeconds(1 / 60 * 3);//大概是三帧的时间
64         Debug.Log("yield WaitForSeconds - step - 2");
65         yield return new WaitForSeconds(1 / 60 * 3);
66         Debug.Log("yield WaitForSeconds - step - 3");
67     }
68 }

运行的结果如下,有点长,我就弄成两张图了:

通过输出我们可以得出下面的结果:

  1. 当帧数波动时,FixedUpdate会进行多次补帧处理,我们可以发现两张图之间FixedUpdate从3一直补帧到15;
  2. WaitForFixedUpdate表示协程是跟在FixedUpdate之后执行的;
  3. WaitForEndOfFrame表示协程是跟在LateUpdate之后执行的;
  4. WaitForSeconds额。。。不用多说了,你指定多久后执行就多久后执行,当然由于是基于帧运算的,所以可能会不准确;

最后补一张开头博客的运行顺序图:

相关文章:

从神经元谈到深度神经网络

作者 | 泳鱼来源 | 算法进阶本文将从神经元到逻辑回归模型结构,并将其扩展到深度深度网络模型。一、谈谈智慧对于人类智慧奥秘的探索,不同时代、学科背景的人对于智慧的理解及其实现方法有着不同的思想主张。有的主张用显式逻辑体系搭建人工智能系统&…

【阿里聚安全·安全周刊】Intel芯片级安全漏洞事件|macOS存在漏洞

关键词:Intel漏洞丨mac OS漏洞丨三星漏洞丨安卓安全丨CPU漏洞丨phpMyAdmin漏洞丨iOS设备|安卓恶意软件检测|Burpsuite 本周资讯top3 【Intel漏洞】芯片级安全漏洞后续:谷歌表示不止Intel,每个1995年后的处理器都可能受影响 1月3日&#xff0c…

BigPipe:高性能的“流水线技术”网页

原文地址:http://www.facebook.com/note.php?note_id389414033919 译文地址:http://isd.tencent.com/?p2419 作者:蒋长浩 Facebook的网站速度做为最关键的公司任务之一。在2009年,我们成功地实现了Facebook网站速度提升两倍 。…

超硬核全套Java视频教程(学习路线+免费视频+配套资料)

文内福利,扫码免费领取Hello,各位锋迷们,我是小千。很多学习Java的小伙伴都在找的全套免费java视频教程,这里全都有,资料齐全,拿来吧你!零基础学Java的学习路线图是怎样的?&#xff…

手机触屏滑动图片切换插件swiper.js

今天给大家分享一款手机触屏滑动图片切换插件swiper.js是一款swiper手机触屏滑动图片幻灯片&#xff0c;适合各种尺寸。效果图如下&#xff1a; 在线预览 源码下载 实现的代码。 html代码&#xff1a; <div style"max-width: 640px; margin: 0 auto;"><di…

Nginx防盗链,Nginx访问控制, Nginx解析php相关配置, Nginx代理

2019独角兽企业重金招聘Python工程师标准>>> Nginx防盗链 Nginx防盗链配置需要与不记录日志和过期时间结合在一起&#xff0c;因为都用到了location。 打开配置文件&#xff0c;注释掉一部分内容&#xff08;红框上方&#xff09;&#xff0c;添加内容&#xff08;红…

web高性能开发系列随笔

在BlogJava里写了一些关于高性能WEB开发的随笔&#xff0c;因为都是跟前端技术相关(html,http,js,css等)&#xff0c;所以也贴到博客园来&#xff0c;吸收下人气。 1、 HTTP服务器. 2、性能测试工具推荐 3、 图片篇. 4、 如何加载JS&#xff0c;JS应该放在什么位置. 5、…

《Effective C++》第8章 定制new和delete-读书笔记

章节回顾&#xff1a; 《Effective C》第1章 让自己习惯C-读书笔记 《Effective C》第2章 构造/析构/赋值运算&#xff08;1&#xff09;-读书笔记 《Effective C》第2章 构造/析构/赋值运算&#xff08;2&#xff09;-读书笔记 《Effective C》第3章 资源管理&#xff08;1&am…

观点:AI 与自动化是矛盾的

作者&#xff1a;cerebralab.com译者&#xff1a;张雨佳原文标题&#xff1a;AI and automation are at odds想象一下&#xff0c;我们生活在一个完美、和谐的地方&#xff0c;所有人在某一天同意让电脑代替人类驾驶汽车&#xff0c;而不是像现在逐步推进自动驾驶。那么&#x…

kaggle之数据分析从业者用户画像分析

数据为kaggle社区发布的数据分析从业者问卷调查分析报告&#xff0c;其中涵盖了关于该行业不同维度的问题及调查结果。本文的目的为提取有用的数据&#xff0c;进行描述性展示。帮助新从业的人员更全方位地了解这个行业。 参考学习视频:http://www.tianshansoft.com/ 数据集&am…

mysql读写分离(MySQL Proxy 安装和使用)

一、必备软件&#xff1a; 1、LUA 可以去LUA的官方下载&#xff1a;www.lua.org 2、MySQL Proxy 这里有好多二进制版本。 http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/ 或者去MYSQL官方下载源代码。 3、测试过程中取消了B和C的REPLICATION。这样SQL语句…

微软副总裁、Kubernetes 头号贡献者的他,给云原生带来奇迹!

我们做了一个街头采访&#xff0c;调查路人眼中的程序员到底是怎样的&#xff1f;提到程序员&#xff0c;大家似乎都有刻板印象&#xff1a;总是格子衬衫牛仔裤双肩包打扮&#xff0c;总是埋头敲代码&#xff0c;加班是常态……谁说程序员呆板木讷&#xff0c;只会埋头敲一行行…

查询Oracle中字段名带.的数据

SDE中的TT_L线层会有SHAPE.LEN这样的字段&#xff0c;使用&#xff1a; SQL>select shape.len from tt_l; 或 SQL>select t.shape.len from tt_l t; 是查询不出来的。 需要这样查询&#xff1a; SQL>select t."SHAPE"."LEN" from tt_l t; 转载于:…

再谈session共享

之前一篇已经写过了《springboot中redis的使用和分布式session共享问题》&#xff0c;但是示例不完全&#xff0c;本文加以完善。 使用spring-session-data-redis解决session共享&#xff0c;而不需要再引入其他jar即可 集成简单&#xff0c;上手迅速。 项目结构 1.pngpom <…

使用MySQL Proxy解决MySQL主从同步延迟

MySQL的主从同步机制非常方便的解决了高并发读的应用需求&#xff0c;给Web方 面开发带来了极大的便利。但这种方式有个比较大的缺陷在于MySQL的同步机制是依赖Slave主动向Master发请求来获取数据的&#xff0c;而且由于服务器负 载、网络拥堵等方面的原因&#xff0c;Master与…

Python 操作 MongoDB 数据库!

作者 |黄伟呢来源 |数据分析与统计学之美MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。先来看看MySQL与MongoDB 概念区别&#xff1a;今天的重点&#xff0c;就是要为大家讲述如何使用Python操…

Linux下用汇编输出Hello, world

下列是Intel汇编语法实现的 Hello, world!程序。 ;; hello.asm ;; nasm -f elf hello.asm; will output hello.o ;; ld -s -o hello hello.o;; section, same to segment segment .data ; 数据段声明, 下列代码将放在数据段中msg db "Hello, world!", 0xA ; 要…

利用bigpipe机制实现页面模块的异步渲染 chunked技术

bigpipe基于HTTP/1.1 支持的chunked编码&#xff0c;可以由浏览器接收到服务器发送的chunked块后&#xff0c;立即解析该块代码。因为chunked编码使消息主体成块发送&#xff0c;每块有自己的大小指示器&#xff0c;在所有的块之后会紧接着一个可选的包含实体头域的尾部。这种编…

hibernate 全面学习【lazy策略 】

2019独角兽企业重金招聘Python工程师标准>>> lazy策略可以用在&#xff1a; * <class>标签上&#xff1a;可以取值true/false * <property>标签上&#xff0c;可以取值true/false&#xff0c;这个特性需要类增强 * <set>/<list>等集合上…

深度学习发现古人类遗址,AI 考古比胡八一更高效

作者 |神经星星来源 |HyperAI超神经By 超神经内容一览&#xff1a;伊利诺伊州立大学人类学专业考古方向的研究人员&#xff0c;将空间遥感技术和深度学习应用于古人类遗址的发掘和研究。关键词&#xff1a;考古 遥感 机器视觉考古&#xff0c;一直是个神秘又充满吸引力的话题。…

linux resource

1. centos repo https://centos.pkgs.org/转载于:https://www.cnblogs.com/gojoin/p/8241068.html

MySQL 水平分区方案Spock Proxy

Spock Proxy 是由实际项目产生的一个开源项目&#xff08;Spock是Rails的应用&#xff0c;Speck Proxy应当可用于Rails之外的&#xff0c;例如PHP或.NET&#xff09;&#xff0c;基于MySQL Proxy开发&#xff0c;是MySQL Proxy的一个分支&#xff0c;支持range-based horizonta…

卷学历、卷加班……程序员拥有什么能力才能破局内卷?

全世界的天才程序员都在疯狂的造轮子&#xff0c;其它程序员只能被动的学习轮子&#xff0c;这简直就像一场绝地求生。程序员行业的内卷已是有目共睹&#xff0c;选择程序员作为职业的人越来越多&#xff1b;大厂对程序员的学历要求越来越高&#xff1b;程序员工作加班越来越严…

LeetCode - Maximum Depth of Binary Tree

递归求二叉树的最大深度。 /*** Definition for binary tree* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ public class Solution {public int maxDepth(TreeNode root) {if(root null)return 0…

2018年IT市场最大的技术趋势和热点预测

随着数字化&#xff0c;物联网&#xff08;IoT&#xff09;设备&#xff0c;区块链应用以及新的服务器战略日益普及&#xff0c;这可能会成为2018年最大的技术趋势。我们期待看到大量与边缘计算相关的新产品&#xff0c;即所谓的无服务器计算&#xff0c;智能家居&#xff0c;智…

哈希分布与一致性哈希算法简介

前言 在我们的日常web应用开发当中memcached可以算作是当今的标准开发配置了。相信memcache的基本原理大家也都了解过了&#xff0c;memcache虽然是分布式的应用服务&#xff0c;但分布的原则是由client端的api来决定的&#xff0c;api根据存储用的key以及已知的服务器列表&…

使用深度学习阅读和分类扫描文档

作者|小白来源|小白学视觉收集数据首先&#xff0c;我们要做的第一件事是创建一个简单的数据集&#xff0c;这样我们就可以测试我们工作流程的每一部分。理想情况下&#xff0c;我们的数据集将包含各种易读性和时间段的扫描文档&#xff0c;以及每个文档所属的高级主题。我找不…

无聊的时候,冷死了(六)

阁下长得真是天生励志&#xff01;好久没有听到有人能把牛吹得这么清新脱俗了&#xff01;你出生时就丑的躲起来了&#xff0c;连你父母都不敢见你&#xff0c;你还怕有人举报你&#xff1f;你拉着一头猪逛街&#xff0c;很幸福的样子&#xff0c;我经过满怀同情的说&#xff1…

Java EE 开发环境搭建

下载安装Java EE SDK 版本&#xff1a;Java Platform,Enterprise Edition 7 SDK (with JDK 7u45) 下载页面&#xff1a; http://www.oracle.com/technetwork/java/javaee/downloads/java-ee-7-sdk-with-jdk-u45-2066865.html 文件名&#xff1a;java_ee_sdk-7-jdk7-windows.exe…

memcacheq 服务安装与原理

memcacheQ是一个单纯的分布式消息队列服务。它的安装依赖于BerkeleyDB 和 libevent&#xff0c;所以要先安装这BerkeleyDB和libevent&#xff1a; 一&#xff0c;BerkeleyDB 下载软件包&#xff0c;http://download.oracle.com/berkeley-db/db-5.0.21.tar.gz解压缩后&#xff…