C#中Coroutine的深层研究
2013-09-22 13:01
267 查看
最近用Coroutine协同程序取代Update的人越来越多,故此我对Coroutine进行了一些研究,以进一步了解该函数的作用,好加快往后游戏的开发效率。
这段文章主要是对拥有一定Coroutine只是的朋友们,若还不了解Coroutine的话可以先去看看Unity3D的文档,再过来做进一步的深层了解。
首先先贴上一段代码:
很简单的一段代码,主要是当CheckInputPartOne的协同程序运行的时候,当我按下空格键,则该协同程序就会被挂起,并开始运行CheckInputPartTwo,直到我放开空格键,输出如下:
不出所料,在CheckInputPartOne挂起了之后,则会直到CheckInputPartTwo结束运行后才会继续运行接下来的字段。
那么接下来我就要稍微为协同程序辟谣一下,曾经看过多个关于协同程序的博文都会对yield return 做出如此解释:
yield return null 表示在1帧后继续以下字段,yield return 2 则为2帧。
这不是真实的,首先我们来看这段实验:
我们在上面的代码中增加一个浮点数变量以用来记载CheckInputPartTwo在yield return 前后间隔的时间差,具体代码如下:
输出如下:
接下来我们将CheckInputPartTwo的 yield return null 改为 yield return 1000,如果说yield return null 是在1帧后返回接下来的字段,那么yield return 1000是不是在1000帧以后返回接下来的字段?我们来看看结果如何:
结果是,所需时间完全一样。其实很简单,yield return 只是为我们执行了IEnumerator的moveNext函数,而后面的值只是因为IEnumerator需要一个IEnumerable作为一个返回值,而IEnumerable其实就是获取一个IEnumerator,因此我们返回yield return 后面的数字或者任何参数其实就是相当于创建并返回了一个IEnumerator,因此无论你设的数字多么的大,上一段与下一段的时间差也永远只是1帧,除非你使用WaitForSeconds,要不然时间差永远都不会有任何改变。
由于我仍然是个还在学习的人,如果有不对还欢迎指出
这段文章主要是对拥有一定Coroutine只是的朋友们,若还不了解Coroutine的话可以先去看看Unity3D的文档,再过来做进一步的深层了解。
首先先贴上一段代码:
public class ResearchCoroutine : MonoBehaviour { void Start () { StartCoroutine ( CheckInputPartOne () ) ; } IEnumerator CheckInputPartOne () { Debug.Log ( "Part One Start" ) ; bool SwitchOffTheLoop = false ; while ( !SwitchOffTheLoop ) { if ( Input.GetButtonDown ( KeyCode.Space ) ) { yield return StartCoroutine ( CheckInputPartTwo () ) ; SwitchOffTheLoop = true ; } yield return null ; } Debug.Log ( "Part One End" ) ; } IEnumerator CheckInputPartTwo () { Debug.Log ( "Part Two Start" ) ; bool SwitchOffTheLoop = false ; while ( !SwitchOffTheLoop ) { if ( Input.GetButtonUp ( KeyCode.Space ) ) { SwitchOffTheLoop = true ; } yield return null ; } Debug.Log ( "Part Two End" ) ; } }
很简单的一段代码,主要是当CheckInputPartOne的协同程序运行的时候,当我按下空格键,则该协同程序就会被挂起,并开始运行CheckInputPartTwo,直到我放开空格键,输出如下:
不出所料,在CheckInputPartOne挂起了之后,则会直到CheckInputPartTwo结束运行后才会继续运行接下来的字段。
那么接下来我就要稍微为协同程序辟谣一下,曾经看过多个关于协同程序的博文都会对yield return 做出如此解释:
yield return null 表示在1帧后继续以下字段,yield return 2 则为2帧。
这不是真实的,首先我们来看这段实验:
我们在上面的代码中增加一个浮点数变量以用来记载CheckInputPartTwo在yield return 前后间隔的时间差,具体代码如下:
public class ResearchCoroutine : MonoBehaviour { private float Timer ; void Start () { StartCoroutine ( CheckInputPartOne () ) ; } IEnumerator CheckInputPartOne () { Debug.Log ( "Part One Start" ) ; bool SwitchOffTheLoop = false ; while ( !SwitchOffTheLoop ) { if ( Input.GetKeyDown ( KeyCode.Space ) ) { Timer = Time.time ; Debug.Log ( "Set Timer" ) ; yield return StartCoroutine ( CheckInputPartTwo () ) ; SwitchOffTheLoop = true ; } yield return null ; } Debug.Log ( "Part One End" ) ; } IEnumerator CheckInputPartTwo () { Debug.Log ( "Part Two Start" ) ; bool SwitchOffTheLoop = false ; while ( !SwitchOffTheLoop ) { if ( Input.GetKeyUp ( KeyCode.Space ) ) { SwitchOffTheLoop = true ; } yield return null ; } Timer = Time.time - Timer ; Debug.Log ( "Time Used: " + Timer ) ; Debug.Log ( "Part Two End" ) ; } }
输出如下:
接下来我们将CheckInputPartTwo的 yield return null 改为 yield return 1000,如果说yield return null 是在1帧后返回接下来的字段,那么yield return 1000是不是在1000帧以后返回接下来的字段?我们来看看结果如何:
结果是,所需时间完全一样。其实很简单,yield return 只是为我们执行了IEnumerator的moveNext函数,而后面的值只是因为IEnumerator需要一个IEnumerable作为一个返回值,而IEnumerable其实就是获取一个IEnumerator,因此我们返回yield return 后面的数字或者任何参数其实就是相当于创建并返回了一个IEnumerator,因此无论你设的数字多么的大,上一段与下一段的时间差也永远只是1帧,除非你使用WaitForSeconds,要不然时间差永远都不会有任何改变。
由于我仍然是个还在学习的人,如果有不对还欢迎指出
相关文章推荐
- C#多线程学习(六) 互斥对象(转载系列)——继续搜索引擎研究
- C++xml文件操作 CMarkup学习方法说明 最近正在研究C++下的XML分析工具CMarkup。初次和XML相遇是基于C#对XML的操作。C#的XmlDocument和XmlNode给我印象
- C# 3.0新特性初步研究 Part1:使用隐含类型的本地变量_C#教程
- c#没有指针导致的性能问题研究一二
- 基于深层神经网络的语音 增强方法研究
- asp.net(C#)中 DataTime 赋空值的研究
- C#程序实现动态调用DLL的研究(转)
- C# 3.0新特性初步研究 Part4:使用集合类型初始化器_C#教程
- Interop(交互) Between C# and C++ 研究一
- C# 3.0新特性初步研究 Part2:使用扩展方法_C#教程
- C# 二进制替换第二弹 二进制替换深入研究---List 与byte[] 效率对比 byte[] 数组 替换
- 基于C#的PISDK研究(代码)
- [最近研究中]C#中的线程
- 字符编码使用-c#研究
- C#各种加密算法的研究
- C#与matlab混合编程的研究与应用
- C#程序实现动态调用DLL的研究
- C# 3.0新特性初步研究 Part1:使用隐含类型的本地变量
- [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2
- unity深入研究--开发之C#使用Socket与HTTP连接服务器传输数据包