Unity3D之协程(Coroutines & Yield )
2015-10-08 14:25
381 查看
写游戏代码,往往最终需要代码为连续的事件.结果会像这样:
[它可以实现将一段程序延迟执行或者将其各个部分分布在一个时间段内连续执行。]
[csharp] view
plaincopyprint?
<span style="font-size:18px;">private int state = 0;
void Update()
{
if (state == 0)
{
//做步骤0
state = 1;
return;
}
if (state == 1)
{
// 做步骤1
state = 2;
return;
}
// ...
} </span>
往往使用yield语句更为方便.yield语句是一个特殊的返回类型,它确保函数从yield语句的下一行继续执行.
[csharp] view
plaincopyprint?
<span style="font-size:18px;">while(true) {
// 做步骤0
yield return 0;
// 等待一帧
// 做步骤1
yield return 2;
// 等待两帧
// ...
} </span>
你也可以传递时间值到yield语句,Update函数会在yield结束后执行下一语句.
[csharp] view
plaincopyprint?
<span style="font-size:18px;"> // do something
yield return WaitForSeconds (5.0);
//等待5秒
// do something more... </span>
你可以入栈并连接协程.
这个例子将执行Do,但是do函数之后的print指令会立刻执行.
[csharp] view
plaincopyprint?
<span style="font-size:18px;">Do ();
Console.WriteLine("This is printed immediately");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
} </span>
这个例子将执行Do,并等待,直到Do完成再执行其他语句.【注:这里的等待是把线程时间交给其他任务,而不是阻塞式等待】
[csharp] view
plaincopyprint?
<span style="font-size:18px;">// 启动协程
yield return StartCoroutine("Do");
Console.WriteLine("Also after 2 seconds");
Console.WriteLine ("这个print将在Do协程执行完以后显示。");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
}
</span>
任何事件处理程序都可以是协同程序 。
注意你不能在Update或FixedUpdate函数内使用yield,但是你能使用 StartCoroutine 开始一个函数.
查看 YieldInstruction , WaitForSeconds , WaitForFixedUpdate , Coroutine and MonoBehaviour.StartCoroutine 可以获得更多使用yield的信息.
yield return可以看做是一种特殊的return,会返回到父类继续执行,但是yield return后面的类型或方法会有一个执行条件,当条件满足时会回调包含yield的子函数,例如下面代码
例1:
[csharp] view
plaincopyprint?
<span style="font-size:18px;">void Start () {
print("Starting:" + Time.time);
StartCoroutine(WaitAnPrint(2.0F));
print("Before WaiAndPrint:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}
</span>
在执行yield return new WaitForSeconds(waitTime)时暂停的条件没有满足,故返回到start函数中继续执行,直到满足条件后再回调WaitAndPrint,所以输出为:
Starting:0
Before WaiAndPrint:0
WaitAndPrint:2.12291
例2:
[csharp] view
plaincopyprint?
<span style="font-size:18px;">IEnumerator Start()
{
print("starting:" + Time.time);
yield return StartCoroutine(WaitAndPrint(2.0F));
print("done:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}</span>
因为start为顶级函数,所以会阻塞在这里,直到StartCoroutine(WaitAndPrint(2.0F))执行完毕,输出为:
starting:0
WaitAndPrint:2.00315
done:2.00315
[csharp] view
plaincopyprint?
<pre name="code" class="csharp"><pre name="code" class="csharp"><pre name="code" class="csharp"><p></p><pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
</pre></pre></pre>
[它可以实现将一段程序延迟执行或者将其各个部分分布在一个时间段内连续执行。]
[csharp] view
plaincopyprint?
<span style="font-size:18px;">private int state = 0;
void Update()
{
if (state == 0)
{
//做步骤0
state = 1;
return;
}
if (state == 1)
{
// 做步骤1
state = 2;
return;
}
// ...
} </span>
往往使用yield语句更为方便.yield语句是一个特殊的返回类型,它确保函数从yield语句的下一行继续执行.
[csharp] view
plaincopyprint?
<span style="font-size:18px;">while(true) {
// 做步骤0
yield return 0;
// 等待一帧
// 做步骤1
yield return 2;
// 等待两帧
// ...
} </span>
你也可以传递时间值到yield语句,Update函数会在yield结束后执行下一语句.
[csharp] view
plaincopyprint?
<span style="font-size:18px;"> // do something
yield return WaitForSeconds (5.0);
//等待5秒
// do something more... </span>
你可以入栈并连接协程.
这个例子将执行Do,但是do函数之后的print指令会立刻执行.
[csharp] view
plaincopyprint?
<span style="font-size:18px;">Do ();
Console.WriteLine("This is printed immediately");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
} </span>
这个例子将执行Do,并等待,直到Do完成再执行其他语句.【注:这里的等待是把线程时间交给其他任务,而不是阻塞式等待】
[csharp] view
plaincopyprint?
<span style="font-size:18px;">// 启动协程
yield return StartCoroutine("Do");
Console.WriteLine("Also after 2 seconds");
Console.WriteLine ("这个print将在Do协程执行完以后显示。");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
}
</span>
任何事件处理程序都可以是协同程序 。
注意你不能在Update或FixedUpdate函数内使用yield,但是你能使用 StartCoroutine 开始一个函数.
查看 YieldInstruction , WaitForSeconds , WaitForFixedUpdate , Coroutine and MonoBehaviour.StartCoroutine 可以获得更多使用yield的信息.
yield return可以看做是一种特殊的return,会返回到父类继续执行,但是yield return后面的类型或方法会有一个执行条件,当条件满足时会回调包含yield的子函数,例如下面代码
例1:
[csharp] view
plaincopyprint?
<span style="font-size:18px;">void Start () {
print("Starting:" + Time.time);
StartCoroutine(WaitAnPrint(2.0F));
print("Before WaiAndPrint:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}
</span>
在执行yield return new WaitForSeconds(waitTime)时暂停的条件没有满足,故返回到start函数中继续执行,直到满足条件后再回调WaitAndPrint,所以输出为:
Starting:0
Before WaiAndPrint:0
WaitAndPrint:2.12291
例2:
[csharp] view
plaincopyprint?
<span style="font-size:18px;">IEnumerator Start()
{
print("starting:" + Time.time);
yield return StartCoroutine(WaitAndPrint(2.0F));
print("done:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}</span>
因为start为顶级函数,所以会阻塞在这里,直到StartCoroutine(WaitAndPrint(2.0F))执行完毕,输出为:
starting:0
WaitAndPrint:2.00315
done:2.00315
[csharp] view
plaincopyprint?
<pre name="code" class="csharp"><pre name="code" class="csharp"><pre name="code" class="csharp"><p></p><pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
</pre></pre></pre>
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- Unity3D中脚本的执行顺序和编译顺序
- Unity3D动态对象优化代码分享
- unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android apk)
- Unity3D游戏引擎实现在Android中打开WebView的实例
- unity3d调用手机或电脑摄像头
- 分享一个开源的网络游戏服务器架构—HouHai
- Unity3D插件详细评测及教学下载
- Unity3D上路_01-2D太空射击游戏
- Unity3D上路_02-第一视角射击游戏
- Unity3D上路_03-塔防游戏
- Unity3D上路_04-基础资源介绍
- Unity3D上路_05-网络相关
- Unity3d TransformPoint 函数研究
- Unity3d 动态加载fbx模型文件
- unity3d地形系统总结