您的位置:首页 > 编程语言 > C#

C#中Coroutine的深层研究

2013-09-22 13:01 267 查看
最近用Coroutine协同程序取代Update的人越来越多,故此我对Coroutine进行了一些研究,以进一步了解该函数的作用,好加快往后游戏的开发效率。

这段文章主要是对拥有一定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,要不然时间差永远都不会有任何改变。

由于我仍然是个还在学习的人,如果有不对还欢迎指出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity 脚本 c#