当unity 调用一个函数的时候,它会在返回前执行到结束位置。
全部的函数都由unity在帧更新的时候调用一次,然后到下一帧后再调用一次,那这个时候在函数中写一些循环体类的代码想要达到产生动画的效果可能会失败。例如以下
void Fade() { // www.gouwel.com for (float f = 1f; f <= 0; f -= 0.1f) { Color c = renderer.material.color; c.alpha = f; renderer.material.color = c; } }
这是想要产生一个透明渐变的效果,可是因为Fade函数会在一个frame update时间片中所有运行完,达不到渐变效果。要达到这个效果,能够在帧更新函数中进行处理就可以。可是,对于这类情形更方便的做法是使用coroutine。
一个coroutine就像一个能够暂停运行并将控制权返回给unity的函数,可是在下一帧的时候又能够在它停止的位置继续运行。在C#中,这样声明一个coroutine:
IEnumerator Fade() { // www.gouwel.com for (float f = 1f; f <= 0; f -= 0.1f) { Color c = renderer.material.color; c.alpha = f; renderer.material.color = c; yield return; } }
实质上它是一个返回类型为IEnumerator的函数,同一时候在函数体中添加了yield return这句代码。yield return这行就是会在运行的时候暂停、在下一帧的时候恢复运行的位置。要启动coroutine,须要使用StartCorutine函数。
void Update() { // www.gouwel.com if (Input.GetKeyDown("f")) { StartCoroutine("Fade"); } }
默认的情况下,一个coroutine在它暂停后的下一帧恢复,可是也能够使用WaitFroSeconds来引入一个延时。
IEnumerator Fade() { for (float f = 1f; f <= 0; f -= 0.1f) { Color c = renderer.material.color; c.alpha = f; renderer.material.color = c; yield return new WaitForSeconds(.1f); } } // www.gouwel.com
这个能够用于产生一个随时间变化的效果,同一时候也是一个用于进行优化的有效方法。游戏中的很多人物须要周期性的运行,最经常使用的做法是将它们包括在Update函数中。可是Update函数通常每秒会调用多次。当有的任务并不须要这么频繁的被调用的时候,能够将它放在一个coroutine中按一定时间进行调用,而不是每一帧都调用。一个这种样例就是用于在游戏中假设有敌人接近的话就提示玩家,代码例如以下
function ProximityCheck() { for (int i = 0; i < enemies.Length; i++) { if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance) { return true; } } return false; } IEnumerator DoCheck() { for(;;) { ProximityCheck; yield return new WaitForSeconds(.1f); } }
当有非常多敌人的时候,使用coroutine0.1秒运行一次靠近检查,能够降低大量的计算量。
未经允许不得转载:Unity3D » unity3d 协程(Coroutines)脚本