必读好文推荐:

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额。。。不用多说了,你指定多久后执行就多久后执行,当然由于是基于帧运算的,所以可能会不准确;

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

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

  1. python3可迭代对象、迭代器、生成器、协程yield入门

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2019-01-24 16:13:07 # @Author : cdl (1217096 ...

  2. python中可迭代对象,迭代器,生成器,协程

    可迭代对象 创建对象的类中有__iter__方法. 它就是可迭代对象. 所谓的可迭代对象,就是可以被遍历的对象. 如果希望遍历能够获取到值,需要让这个__iter__方法返回一个迭代器对象 迭代器 创 ...

  3. 学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)

    立即学习:https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu 协程(yield,greenlet,gevent) 1. ...

  4. unity update 协程_Unity协程,停止协程及yield return使用_019

    public void Start() { //开启协程 Coroutine testCoroutine = StartCoroutine(Test()); //停止指定协程 StopCoroutin ...

  5. Unity 协程 yield return的使用

    public void Start(){//开启协程Coroutine testCoroutine = StartCoroutine(Test());//停止指定协程StopCoroutine(tes ...

  6. (转)python协程2:yield from 从入门到精通

    原文:http://blog.gusibi.com/post/python-coroutine-yield-from/ https://mp.weixin.qq.com/s?__biz=MzAwNjI ...

  7. python协程--yield和yield from

    字典为动词"to yield"给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 n ...

  8. 理解Python的协程机制-Yield

    根据PEP-0342 Coroutines via Enhanced Generators,原来仅仅用于生成器的yield关键字被扩展,成为Python协程实现的一部分.而之所以使用协程,主要是出于性 ...

  9. 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】...

    Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...

最新文章

  1. 浏览器对象模型:window对象2
  2. 解读网络“攻城狮”的发展---老赵带你铺一段路
  3. SegmentFault Hackathon 2018 火热登场,Let's hack!
  4. fprintf函数的用法matlab_极力推荐这个Matlab教程
  5. java基础之设计模式
  6. 01-UIScrollView01-大图片展示
  7. 如何输入一个整数逆序输出_如何理解运算放大器的共模输入和输出摆幅限制?...
  8. android之隐藏状态栏、图标、布局
  9. NGN学习笔记7——NGN的服务质量
  10. eplan p8详细安装步骤文库_eplan p8详细安装步骤
  11. 新手到黑客的最全入门路径图(附全部学习资料下载)!
  12. c语言中next如何用,C++ STL prev()和next()函数用法详解
  13. 2、进入缓冲区(缓存)的世界,破解一切与输入输出有关的疑难杂症(转载自C语言中文网,仅作学习笔记)
  14. 一建网课一级建造师精讲班视频课件建筑市政机电法规管理经济
  15. 万能应用市场删除后台自动安装
  16. HTTPS工作原理及报文讲解
  17. 基于Python3(Autosub)以及Ffmpeg配合GoogleTranslation(谷歌翻译)为你的影片实现双语版字幕(逐字稿)
  18. C语言教程:十进制转换任意进制
  19. C# 特殊运算符 |,,^的运用
  20. 计算机名更改后无法进入局域网,win10系统局域网计算机名称更改的恢复办法

热门文章

  1. Markdown解决图片存储问题
  2. 从难免的线上bug说起代码的思考
  3. VS2005 常用快捷键
  4. Linux wait函数解析
  5. WMI技术介绍和应用——Event Provider
  6. 吴恩达老师深度学习视频课笔记:神经风格迁移(neural style transfer)
  7. 吴恩达老师深度学习视频课笔记:目标检测
  8. 吴恩达老师深度学习视频课笔记:构建机器学习项目(机器学习策略)(2)
  9. 【leetcode】力扣刷题(2):两数相加(go语言)
  10. java 办公,中文JAVA技术网