协程用途广泛,甚至可以用来控制动画效果。在手游时代著名的游戏引擎Unity 3D内置了C#作为脚本语言的支持。C#有和Python的generator几乎一样的语法(叫做Enumerator),而C#的Enumerator在Unity 3D被用作控制一个动画的过程的工具。本文是 http://unitygems.com/coroutines/ 这篇文章的一个摘要。
协程是一个可被中断然后又被继续的函数执行过程,在Unity 3D中,这个继续又中断的动机就是动画是一帧一帧的(Frame)。控制动画的协程会在每一帧中被执行一下,然后又被中断,然后又在下一帧中继续,如此往复:
代码写出来就是这个样子的:
IEnumerator Die()
{
//Wait for the die animation to be 50% complete
yield return StartCoroutine(WaitForAnimation("die",0.5f, true));
//Drop the enemies on dying pickup
DropPickupItem();
//Wait for the animation to complete
yield return StartCoroutine(WaitForAnimation("die",1f, false));
Destroy(gameObject);
}
Die函数控制了一个动画人物的死亡过程。yield了之后,函数就不在被执行了,直到yield的子协程执行完了,引擎才会继续执行yield后面的动画动作。而其中的WaitForAnimation的子协程是真正细化到每一帧的动画播放过程了:
IEnumerator WaitForAnimation(string name, float ratio, bool play)
{
//Get the animation state for the named animation
var anim = animation[name];
//Play the animation
if(play) animation.Play(name);
//Loop until the normalized time reports a value
//greater than our ratio. This method of waiting for
//an animation accounts for the speed fluctuating as the
//animation is played.
while(anim.normalizedTime + float.Epsilon + Time.deltaTime < ratio)
yield return new WaitForEndOfFrame();
}
把代码用协程这样写的好处是什么?就是Logic Locality,前后相关的逻辑放在一个函数内,比分散在多个回调函数中要更容易理解。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。