Unity 协程Coroutine综合测试

  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Text;
  4
  5 public class rotCube : MonoBehaviour {
  6
  7     //示例,如何为一个自定义对象实现GetEnumerator接口,从而可以对该对象使用foreach
  8     //这种写法是c#2.0才有的,通过yield关键字与IEnumerator返回类型组合成一个枚举器
  9     //C#会自动生成一个IEnumerator类,该类实现了MoveNext(),Reset(),Current
 10     //在C#2.0之前,我们必须自己来写一个IEnumerator类,才实现上面的接口与属性
 11     class MyCalc : IEnumerable{
 12         int rest = 1;
 13         public int x = 1;
 14         public int y = 1;
 15
 16         public IEnumerator GetEnumerator ()
 17         {
 18             for(int i=0; i<y; ++i)
 19             {
 20                 yield return rest = x * rest;
 21             }
 22         }
 23     }
 24
 25     //示例,如何将一个函数写成可以被枚举的对象(拥有MoveNext(),Reset(),Current)
 26     //C#会自动生成一个IEnumerator类,该类实现了MoveNext(),Reset(),Current
 27     //在C#2.0之前,我们必须自己来写一个IEnumerator类,才实现上面的接口与属性
 28     IEnumerable calc(int x, int y){
 29         int rest = 1;
 30         for(int i=0; i<y; ++i)
 31         {
 32             yield return rest = x * rest;
 33         }
 34     }
 35
 36     IEnumerator waitprint(){//协程返回类型必须为IEnumerator,它不认IEnumerable,如yield return DoCheck (),若DoCheck为IEnumerable,则DoCheck不会被执行
 37
 38         //StartCoroutine("DoCheck");//启动一个新的协程
 39         //yield return DoCheck (); //在这里进入死循环,若改为StartCoroutine("DoCheck");则不会进入死循环,只会另外启动一个协程
 40
 41         yield return new WaitForSeconds (5); //暂停5秒,若流程走到了这里,协程将在这里阻塞5秒才执行下面的代码
 42         yield return new GameObject ();
 43         yield return 2;
 44     }
 45     IEnumerable waitPrint(){
 46         yield return 1;
 47         yield return 2;
 48     }
 49
 50     IEnumerator DoCheck(){
 51         for(;;){
 52             Debug.Log ("doecheck");
 53             //协程调用频率最高是每帧一次,这里我们指定的等待时间小于一帧,并不能达到一帧调用多次docheck的效果
 54             yield return new WaitForSeconds (0.0001f); //0.1毫秒,1/0.0001F = 10000 fps,显然U3D不可能达到这个帧率
 55         }
 56     }
 57
 58     void Start () {
 59
 60         /************************************************************************/
 61         /* 自定义对象的枚举测试,自定义方法的枚举测试,这是理解协程的基础            */
 62         /************************************************************************/
 63         StringBuilder sbd = new StringBuilder(50);
 64         foreach(var n in calc (2, 8)){
 65             sbd.Append (n);
 66             sbd.Append (",");
 67         }
 68
 69         sbd.Length = 0;
 70         MyCalc omc = new MyCalc (){ x = 2, y = 8 };
 71         foreach(var n in omc){
 72             sbd.Append (n);
 73             sbd.Append ((","));
 74         }
 75
 76
 77         /************************************************************************/
 78         /* 协程综合测试                                                          */
 79         /************************************************************************/
 80         //U3D协程特征:本质是一个返回值为IEnumerator的函数,函数中至少有一条yield return语句。
 81         //协程必须由StartCoroutine来启动
 82         //协程并非线程,线程是操作系统层的东西,协程是引擎层面由逻辑调用来实现的,是由一个线程操作出来的,在LUA中是由LUA状态机实现,在U3D是由U3D引擎状态机实现。
 83         //在U3D中,协程是U3D引擎在每帧的update之后调用一次协程函数来实现,在update()中写一个死循环,会发现程序卡死,协程也不会执行了。这证明了协程和主线程是同一线程。
 84         //UNITY手册的Execution Order of Event Functions一节详细讲解了协程的调用时机,从中可以看出协程只是主线程中的逻辑调用,并非一个新线程。
 85
 86         //StartCoroutine ("DoCheck");
 87         //yield return waitprint (); //waitprint被完整执行
 88         //yield return waitPrint (); //waitPrint没有被执行,U3D不认这种形式
 89
 90
 91         //协程返回类型必须为IEnumerable。
 92         //但不管一个函数的返回类型是IEnumerable还是IEnumerator,只要函数体中有一句yield return,编译器就会自动为该函数生成一个IEnumerator类型的对象。
 93         //就可以使用此迭代器对象的MoveNext(), Current等方法,属性。若是返回类型为IEnumerable,编译器还会生成GetEnumerator()方法。
 94         waitprint ();//直接调用协程函数无效,不会进入该函数执行,这时仅相当于返回了一个IEnumerator迭代子的临时对象,并没有执行具体代码。
 95
 96         //只有如下调用,才会完整的执行协程函数
 97         IEnumerator i = waitprint ();
 98         i.MoveNext (); //从函数入口执行到yield return new WaitForSeconds (5);
 99         i.MoveNext (); //从上一个yield语句末执行到yield return new GameObject ();
100         i.MoveNext (); //从上一个yield语句末yield return 2;
101         //下面这种写法并不能达到上面的效果,原因是每次waitprint ()返回的是一个不同的临时对象,通过gethashcode可以发现。
102         //waitprint ().MoveNext ();
103         //waitprint ().MoveNext ();
104         //waitprint ().MoveNext ();
105
106         //返回值为IEnumerable类型的示例
107         //只有返回值为IEnumerable的方法才能用于foreach,因为它要求实现GetEnumerator
108         i = waitPrint ().GetEnumerator ();
109         i.MoveNext ();
110         i.MoveNext ();
111         i.MoveNext ();
112
113         print ("done");
114     }
115
116     void Update(){
117         transform.Rotate (0, 2, 0);
118     }
119 }

posted on 2016-10-21 20:09 时空观察者9号 阅读(...) 评论(...) 编辑 收藏

Unity 协程Coroutine综合测试相关推荐

  1. 【Unity】Unity协程(Coroutine)的原理与应用

    文章目录 前言 一.什么是协程 二.应用场景 1.异步加载资源 2.将一个复杂程序分帧执行 3.定时器 三.协程的使用 注意事项 四.Unity协程的底层原理 1. 协程本体:C#的迭代器函数 2. ...

  2. Unity 协程(Coroutine)原理与用法详解

    前言: 协程在Unity中是一个很重要的概念,我们知道,在使用Unity进行游戏开发时,一般(注意是一般)不考虑多线程,那么如何处理一些在主任务之外的需求呢,Unity给我们提供了协程这种方式 为啥在 ...

  3. unity协程coroutine 简明教程

    本篇内容基于 https://gamedevbeginner.com/coroutines-in-unity-when-and-how-to-use-them/ 以及官方教程 为什么使用协程 协程非常 ...

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

    Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine ...

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

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网 ...

  6. Unity 协程原理探究与实现

    目录 一.介绍 二.迭代器 三.原理 四.总结 一.介绍 协程Coroutine在Unity中一直扮演者重要的角色.可以实现简单的计时器.将耗时的操作拆分成几个步骤分散在每一帧去运行等等,用起来很是方 ...

  7. Unity协程实现分析以及Lua协程与Unity协程的混合使用

    1,节选翻译一篇stackoverflow关于Unity协程实现的讨论 - The big clues are in the C# version. Firstly, note that the re ...

  8. lua协程 unity_unity协程coroutine浅析

    一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下,通过前辈的文章大体理解了一下,在这儿抛砖引玉写一些个人理解.当然首先给出几篇 ...

  9. unity 协程特点

    协程 一. Unity中使用协程 1. 什么是协程 2. 如何使用 3. 协程的应用场景 创建补间动画 打字机效果 异步加载资源 4. 注意事项 二. Unity协程的底层原理 1. 协程本体:C#的 ...

最新文章

  1. 【Python数据挖掘课程】五.线性回归知识及预测糖尿病实例
  2. Windows Mobile下C++取屏幕分辨率的方法
  3. 数据结构:用栈实现中缀表达式的求值(文字描述+详细步骤示例)
  4. PCM信号是什么信号?
  5. winform中DataGridview数据绑定时格式化文本,如:将部分文字改成绿色,部分文字改成红色...
  6. wget在进行https下载时超时不生效问题
  7. python程序中1—10的乘积_[求助]1个数1到10的乘积
  8. 调试笔记:BSOD 0xA
  9. java 打印 日历 详细 注解_Java实现按年月打印日历功能【基于Calendar】
  10. 伊斯兰教历的计算和各个月的名称
  11. 服务器上qq邮件不能打开方式,QQ邮箱打不开是怎么回事?从QQ面板上打不开QQ邮箱怎么解决?...
  12. LWN:5.18合并窗口第一部分!
  13. 机器学习实战之信用卡诈骗(二)
  14. Git入门-github
  15. java实现微博后台登录后台发送微博
  16. 基于Binlog、FlinkCDC、Doris实现实时数据同步
  17. x265-1.7版本-common/lowres.cpp注释
  18. stm32f105vct6例程_STM32F105VCT6
  19. Linux系统一键安装可视化桌面环境支持浏览器及RDP访问
  20. 计算机和用户交互的界面是显示器吗,人机交互与人机界面的区别

热门文章

  1. CentOS7中离线安装Docker与卸载
  2. Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口
  3. 【NLP实战】Task2:特征处理
  4. flutter - dart基础之map
  5. 视频 + PPT | 数字化运营,从理论到实践
  6. 喜报 | 链家签约神策数据,让数据“说话”更精准
  7. Object构造函数的方法
  8. python 错误、调试和测试
  9. C# winfrom 通过代码 删除TableLayoutPanel控件的一行或列
  10. Monkey Server自动化脚本