Unity教程合集Unity基础入门分享unity修炼之路

[Unity][基础篇]协程

2016-12-04  本文已影响223人  tmgg

为什么需要协程

在游戏中有许多过程(Process)需要花费多个逻辑帧去计算。

不管什么时候,如果你想创建一个能够历经多个逻辑帧的流程,但是却不使用多线程,那你就需要把一个任务来分割成多个任务,然后在下一帧继续执行这个任务。

比如,A算法是一个拥有主循环的算法,它拥有一个open list来记录它没有处理到的节点,那么我们为了不影响帧率,可以让A算法在每个逻辑帧中只处理open list中一部分节点,来保证帧率不被影响(这种做法叫做time slicing)。

再比如,我们在处理网络传输问题时,经常需要处理异步传输,需要等文件下载完毕之后再执行其他任务,一般我们使用回调来解决这个问题,但是Unity使用协程可以更加自然的解决这个问题如下边的程序:

private IEnumerator Test() { 
  WWW www = new WWW(ASSEST_URL);
  yield return www; 
  AssetBundle bundle = www.assetBundle;
}

协程是什么

协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。

从程序结构的角度来讲,协程是一个有限状态机,这样说可能并不是很明白,说到协程(Coroutine),我们还要提到另一样东西,那就是子例程(Subroutine),子例程一般可以指函数,函数是没有状态的,等到它return之后,它的所有局部变量就消失了,但是在协程中我们可以在一个函数里多次返回,局部变量被当作状态保存在协程函数中,知道最后一次return,协程的状态才别清除。

简单来说,协程就是:你可以写一段顺序的代码,然后标明哪里需要暂停,然后在下一帧或者一段时间后,系统会继续执行这段代码。

协程的作用一共有两点:
1)延时(等待)一段时间执行代码;
2)等某个操作完成之后再执行后面的代码。
总结起来就是一句话:控制代码在特定的时机执行。

协程运行的原理

Paste_Image.png

参照上图,协程跟Update()其实一样的,都是Unity每帧对会去处理的函数(如果有的话)。如果MonoBehaviour 是处于激活(active)状态的而且yield的条件满足,就会调用协程的代码。如果是 yield return null ,就会在同一帧再次被唤醒。
  协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法 Current 和 MoveNext() ,迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。unity3d在每帧做的工作就是:调用协程(迭代器)MoveNext() 方法,如果返回 true ,就从当前位置继续往下执行。

协程怎么灵活运用

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(); 
    }
}
IEnumerator UntilTrueCoroutine(Func fn) { 
    while(!fn()) yield return null;
} 
Coroutine UntilTrue(Func fn) { 
    return StartCoroutine(UntilTrueCoroutine(fn));
} 
IEnumerator SomeTask() { 
    /* ... */ 
    yield return UntilTrue(() => _lives < 3); 
    /* ... */
}

总结

上一篇 下一篇

猜你喜欢

热点阅读