关于C# IEnumerator、yield、Unity3D协程的一些东西
2015-10-22 13:18
676 查看
在学习Unity3D的协程,其中需要C#中IEnumerator的使用,主要在看http://www.cnblogs.com/neverdie/p/3792766.html这篇文章。
对其中一些地方一开始没太看懂,看懂以后总结在这里。
(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
关于这一段一开始不太懂,不明白第一个yield前面为什么要加while(后面两个同理),后来想明白了,是在PlayAnimation这个播放动画函数所播放的动画结束前,playingAnimation这个bool一直为true,这样写可以避免播放动画过程中调用TellMeASecret的MoveNext后开始执行Say函数的结果,这个结果是不应该发生的。
自己总结一下,IEnumerator的使用,就像是一个函数内部可以通过for循环if判断等逻辑语句甚至是与函数外部变量共同动态维护的顺序执行队列,在函数外部通过MoveNext来依次执行队列中的语句。
Unity3D中yield的几种基本用法:(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
yield的几种灵活用法:(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
第二个,由于一个协程只是一个迭代器块而已,所以你也可以自己遍历它,这在一些场景下很有用,例如在对协程是否执行加上条件判断的时候:
第三个,由于协程可以yield协程,所以我们可以自己创建一个协程函数,如下:
关于yield的WaitsForSeconds()的用法
private IEnumerator DelayExcute(float delayTime = 0.5f)
{
//statement1
yield return new WaitForSeconds(delayTime);
//statement2
}
public void UnLightHightGameObjs(float duration = 0.5f)//遮罩层消失
{
PlayAnim();//先播放动画
StartCoroutine(DelayExcute());//延迟执行 //方法一
IEnumeratore = DelayExcute();
//方法二(包括while)
while(e.MoveNext)
{
//statement
}
}
项目里有一个半秒的动画,动画完毕需要执行一个函数DelayExcute(),一开始使用的是方法二的用法,以为能在半秒后才执行DelayExcute(),结果效果还是直接执行了。
搜了一下采用了方法一,成功了。
想了一下,猜测MoveNext()就是强行把指针移到下一个yield的地方,并且执行与上一个yield之间的函数,而StartCoroutine()则是解析到WaitForSeconds()函数后设定了一个半秒后执行的延迟。
对其中一些地方一开始没太看懂,看懂以后总结在这里。
(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
IEnumerator TellMeASecret(){ PlayAnimation("LeanInConspiratorially"); while(playingAnimation) yield return null; Say("I stole the cookie from the cookie jar!"); while(speaking) yield return null; PlayAnimation("LeanOutRelieved"); while(playingAnimation) yield return null; }(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
关于这一段一开始不太懂,不明白第一个yield前面为什么要加while(后面两个同理),后来想明白了,是在PlayAnimation这个播放动画函数所播放的动画结束前,playingAnimation这个bool一直为true,这样写可以避免播放动画过程中调用TellMeASecret的MoveNext后开始执行Say函数的结果,这个结果是不应该发生的。
自己总结一下,IEnumerator的使用,就像是一个函数内部可以通过for循环if判断等逻辑语句甚至是与函数外部变量共同动态维护的顺序执行队列,在函数外部通过MoveNext来依次执行队列中的语句。
Unity3D中yield的几种基本用法:(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
Normal coroutine updates are run after the Update function returns. A coroutine is a function that can suspend its execution (yield) until the given YieldInstruction finishes. Different uses of Coroutines: yield; The coroutine will continue after all Update functions have been called on the next frame. yield WaitForSeconds(2); Continue after a specified time delay, after all Update functions have been called for the frame yield WaitForFixedUpdate(); Continue after all FixedUpdate has been called on all scripts yield WWW Continue after a WWW download has completed. yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to complete first.
yield的几种灵活用法:(出处 http://www.cnblogs.com/neverdie/ ,By 王选易)
YieldInstruction y; if(something) y = null;else if(somethingElse) y = new WaitForEndOfFrame();else y = new WaitForSeconds(1.0f); yield return y;
第二个,由于一个协程只是一个迭代器块而已,所以你也可以自己遍历它,这在一些场景下很有用,例如在对协程是否执行加上条件判断的时候:
IEnumerator DoSomething(){ /* ... */} IEnumerator DoSomethingUnlessInterrupted(){ IEnumerator e = DoSomething(); bool interrupted = false; while(!interrupted) { e.MoveNext(); yield return e.Current; interrupted = HasBeenInterrupted(); }}
第三个,由于协程可以yield协程,所以我们可以自己创建一个协程函数,如下:
IEnumerator UntilTrueCoroutine(Func fn){ while(!fn()) yield return null;} Coroutine UntilTrue(Func fn){ return StartCoroutine(UntilTrueCoroutine(fn));} IEnumerator SomeTask(){ /* ... */ yield return UntilTrue(() => _lives < 3); /* ... */}
关于yield的WaitsForSeconds()的用法
private IEnumerator DelayExcute(float delayTime = 0.5f)
{
//statement1
yield return new WaitForSeconds(delayTime);
//statement2
}
public void UnLightHightGameObjs(float duration = 0.5f)//遮罩层消失
{
PlayAnim();//先播放动画
StartCoroutine(DelayExcute());//延迟执行 //方法一
IEnumeratore = DelayExcute();
//方法二(包括while)
while(e.MoveNext)
{
//statement
}
}
项目里有一个半秒的动画,动画完毕需要执行一个函数DelayExcute(),一开始使用的是方法二的用法,以为能在半秒后才执行DelayExcute(),结果效果还是直接执行了。
搜了一下采用了方法一,成功了。
想了一下,猜测MoveNext()就是强行把指针移到下一个yield的地方,并且执行与上一个yield之间的函数,而StartCoroutine()则是解析到WaitForSeconds()函数后设定了一个半秒后执行的延迟。
相关文章推荐
- 集成讯飞听写iOS sdk到unity遇到的问题:weak成员和strong成员
- 转场不销毁物体 esc退出,图片挡住按钮怎么办,Canvas Group组,blocks Raycasts
- Unity3D系列2:Input.GetButtonDown没有正确响应
- Spine输出资源一键入Unity3D工具代码
- Unity调试函数执行时间
- 解决Unity5+Vuforia+Network本地联机发布到Android上白屏的问题
- Unity获取object所有属性的一个方法,一些界面上没有开放的属性可以用该方法编辑
- ZXing二维码生成在Unity3D中出错,数组超出界限的解决办法
- [Unity3D学习]3D数学基础之坐标系
- Unity3D游戏开发初探—2.初步了解3D模型基础
- 【Unity Shaders】Surface Shader 概述
- 【笨木头Unity】入门之旅003:HelloWorld
- 【笨木头Unity】入门之旅002:不谈对象,咱们谈组件
- Unity3D优化
- unity3d Vector3.Dot Cross Angle 用法记录
- unity3d 通过代码建立曲面
- UNITY 5.2 SystemInfo类
- unity 脚本编译顺序
- unity 脚本编译顺序
- Unity编辑器下获取动画的根运动状态并修改