在看别人代码的时候总是发现有个StartCoroutine(XXXXXX()),刚开始根本不明觉厉,只好查查单词。
Coroutine翻译过来是协同程序,那么什么是协同程序,又去百度了下,发现大多的解释是协同程序就像一个线程,占用少量的资源,不过并不是由系统调用,是由程序员调用,但是一经启动就无法停止下来(除非Stop)。
在u3d中,StartCoroutine()必须结合IEnumerator来使用,何谓IEnumerator,IEnumerable和IEnumerator 详解,这篇博文详细地解释了IEnumerator。
一个IEnumerator的方法在其每一条路径上都必须用yield return进行返回,经常用的大致有一下几种返回值
//等待XX秒后执行下面的语句。
yield return new WaitForSeconds(XX);
//等待加载完毕。
yield return new WaitForEndFrame();
//等待FixedUpdate完毕。
yield return new WaitForFixedUpdate()
//等待下一帧。
yield return null;
yield return只要理解为“等待什么完成”就可以了。
Coroutine广泛运用于u3d中,其中一个优点就是延时。
先举个例子,我们在做游戏中经常会遇到倒计时的制作。
在不使用Coroutine的情况下,一般我是这么实现的
<pre name="code" class="html">float createTime=3f;
void Update()
{
createTime-=Time.deltaTime;
}
void OnGUI()
{
if(createTime>0)
{
GUI.Label(new Rect(Screen.width/2,Screen.height/2,20f,20f),createTime.ToString("F0"));
}
}
在用Coroutine的情况下,我是这么实现的
int createTime=3;
void OnGUI()
{
if(createTime>0)
{
StartCoroutine(TimeCutDown(1));
GUI.Label(new Rect(Screen.width/2,Screen.height/2,20f,20f),createTime.ToString());
}
}
IEnumerator TimeCutDown(float gap)
{
yield return new WaitForSecond(gap);
createTime--;
StopAllCoroutine();
}
看上去不用Coroutine比用Coroutine简单,可是你必须得在每一帧都计算一次倒数的时间,若你一个游戏里面有几十个倒数,你必须得分清所有计时器,并逐一计算。而用Coroutine,你在想用延时时只需要写上
StartCoroutine(TimeCutDown(XX));
随便来多少个倒计时。
使用Coroutine的第二个优点,也是最大的一个优点,就是异步。
何谓异步,举个例子,我们在想要制作Loading界面的时候,总想要在Loading界面同时加载其他界面,当其他界面加载完毕的时候,就跳出Loading界面而显示其他界面。这就是异步。
Unity3d中制作Loading场景进度条所遇到的问题,这篇文章很好的阐述了如何异步实现Loading界面。
总之,任何我们想同时进行的工作,首先我们就可以想想用Coroutine能不能实现,个人认为还是挺方便的。
Coroutine的第三个优点就是,它会一直执行下去,除非停止。
这跟for循环的区别在于 Coroutine执行没有条件,而是当你停止的时候才停止,否则会无限循环。
那这还算优点吗?这不是加大CPU负荷吗?
我们在制作游戏的时候总有一些东西是要全程判断的,比如胜利与否、死亡与否以及角色该执行的动作,当然我们可以写在update()里面进行判断,但是有时候我们并不想写在update()里面,可能是因为里面的东西太多了,也可能是单纯的不想写在update()里,所以我们可以使用StartCoroutine(),它就只会在Start()或者Awake()里面调用一次,然后一直执行下去除非你停止。
Unity手游之路<十>自动寻路Navmesh之跳跃,攀爬,斜坡,从这里我们看到,作者就是在Start()里用StartCoroutine()实现角色动作的全程监控,实时改变人物的动作。