Unity 协程与线程

Unity 协程与线程

协程是不同步的

协程 不是 线程,协同程序是
不同步 的

     
一个线程在程序中同外线程是异步运行的,在多处理器机器中一个线程可以又和有着其他线程的实时运行该代码,这令线程编程能够解决好复杂的事务,因为可能当同样之光阴里一个线程在转它如果其他一个线程正在读取它,这象征任何一个线程实际上可以变更之事物在玩耍被拍卖的中级犹如是您的源代码一行。这是以你写的代码是由机械变成汇编语言,更是再次扑朔迷离。正因为这样,你要经锁,以保险这种景象不会见由于其他保管没有共享内存发生。或者经过锁定任何线程使用同一片内存,当他们以读取或变更时。

什么是协程?

     
协同程序绝对免是一个线程。这表示在同一时间只生一个协同程序在推行,它见面让实施于玩乐之主线程上,所以实际上在同一时间游戏的中心只生一个协同程序在运行[随即段翻译的未极端可靠]

*     你永远不欲担心联合还是锁定一个值当你方编制一个协同程序。你发完全的控制权,直到你的代码执行到
yiedld*

  因此总结一下协程的概念

   
协程只是有些实行,并而在相当的尺度得满足,在未来的某部同时时以吃恢复,直到其的干活形成

Unity函数执行图

Unity processes coroutines every frame of the game for every object that
has one or more running.  The processing occurs after Update and before
LateUpdate for most yield statements, but there are special cases:

Unity的流水线协同程序在戏之每一样幅每个对象为保有一个还是多个在周转的。Update()
之后,LateUpdate()之前 ,发生的 yield 语句子之拍卖,但为出新鲜情况

图片 1

When the coroutine is activated it will execute right up to the next
yield statement and then it will pause until it is resumed.  You can see
where it will resume in the diagram above, based on what you yield.

当协程被激活,它见面直接到下一个
yield语句执行,然后其见面搁浅,直到其过来。你可以于直达图中视其见面卷土重来,根据你的
yield语句。

简简单单的协程示例

叫咱来探视一个非常简单的协程

IEnumerator TestCoroutine()
{
      while(true)
      {
           Debug.Log(Time.time);
           yield return null;
      }
}

该协程将会见永远执行下。它记录时的时,然后yield,当它们深受还原,它同时进来了之轮回,记录一致次于时间,遇到
yield 并重新之前的操作

The code inside the loop is exactly like an Update function.  It
runs once every frame for this object, just after the script’s Update
routine runs (if it has one).

立马代码循环就如 Update() 函数。这个目标在列一样轴中运作,脚本的Update
程序运行后(如果有的话)

When you call StartCoroutine(TestCoroutine()) the code executes
immediately up to the first time it yields, it will then be resumed when
Unity processes coroutines for this object.

当你调用 StartCoroutine(TestCoroutine()) 代码立即第一不好得到实施 然后
yield,当Unity 引擎再次拍卖此GameObject时,协程会于还原

If you start a coroutine early in the
processing of a game object, like creating one in Start, Update or
OnCollisionEnter then that coroutine will immediately run up to the
first yield, then it will resume during the same frame if you yield
return null .

假若你在早于Unity处理及GameObject就推行一个协程
比如
Start(),Update()或OnCollisionEnter()将会晤继续执行,当第一次于遇到yield,然后同一帧会恢复,如果您yield
null。有时候会生竟的结果,如果您莫考虑她。

 

是不是会尽循环

今昔还发生同等桩事,在咱们的测试协程显然不是最为循环

下列情形协程将会晤不再被实施:如果你扭曲打电话,会告一段落游戏对象的协同程序,如果其让销毁,它不会见重新运行。如果下论为直接或通过玩对象上动SetActive(false),它为未会见再实行。

I Yield Sir

Unity processes coroutines every frame of the game for every object that
has one or more running.

Unity于拍卖协程时凡
在娱乐之每一样幅,每一个GameObject上展开的,可以处理1只或多独

您或许也想啊,不,它不需,如果您以这样的

yield return new WaitForSeconds(1)then it
doesn’t process it for another 1 second!”那么其不处理它的另外1秒Well
actually Unity does process that coroutine every frame, checking to see
if the right amount of time has elapsed – it doesn’t process your code,
but it does process the coroutine which is the wrapper its made around
your script.那么实际上,Unity
会处理协程在各级一样轴,检查合适的时是不是业已过去,它不会见处理你的代码,但是她会处理这个协程,是若的脚本在卷入这个协程因此我们掌握,我们好使得的暂停我们的代码通过
yield ,下面是那些你可以Return 的:

  • null
    -协程执行下一样不良,它是合格的
  • WaitForEndOfFrame –
    协程的框架上实施,在颇具的渲染和图形用户界面完成以后
  • WaitForFixedUpdate –
    导致这个协程在产一致次等物理学的步骤执行,在具有的物理计算后
  • WaitForSeconds –
    使协程并无是一个一定的娱乐时间内履
  • WWW –
    waits for a web request to complete (resumes as if WaitForSeconds or
    null)
  • Another
    coroutine – in which case the new coroutine will run to completion
    before the yielder is
    resumed(在这种状况下,新的协同程序将以此Yield恢复之前到位)

You
can also issue the command yield break; which immediately stops the
coroutine.你还足以有 yield break
命令,去这停下这协程Because of
WaitForEndOfFrame coroutines can be used to get information from render
textures when all cameras have completed rendering and the GUI has been
displayed因为
WaitForEndOfFrame 协程可以用于从渲染纹理中获取信息,
当所有的Camera已好渲染 并且 GUI 已经于显示Using
yield return new WaitForSeconds(x) will never resume if the
Time.timeScale is set to 0.运 yield
return new WaitForSeconds(x) 将永久不见面为还原,如果 Time.timeScale
=0Of course
the great thing about all of this is that you can write code that needs
to execute over a period of time, or wait for some external event to
occur, and keep it all nicely together in a single function making your
code far more readable than if you had to write multiple functions or
lots of code to keep checking the state of things.当然,关于这总体的宏大之政工是,你可形容用执行一段时间,或者等待发生有表事件,并维持它有着时尚典雅的同一从在一个单纯的效用而您的代码更易于读的代码比,如果您不得不编写多独函数的代码或所在继续检查东西之状态。这是当真的协同程序的境地。

 

总结:

  1. Coroutines are
    a really good way of making a sequence of operations happen over
    time or when some external process is completed
  2. Coroutines are
    not threads and are not asynchronous
  3. Nothing else
    is running when your coroutine is executing
  4. Your coroutine
    will resume when the conditions of your yield statement are met

  5. Coroutines are
    inactive when the script is disabled or the object is destroyed

  6. yield return new
    WaitForSeconds is dependent on game time which is affected by
    Time.timeScale

译:

  1. 协程通过本顺序的操作 或一些事实上的拍卖 当它形成时
  2. 协程并无是线程,它从未联手
  3. 从来不其它 或曾经在运作协程
  4. 而的协程

 

协程的实际上用

可望咱们曾了解了协程是什么,以及它于运行时。我们的高等教程将研究该技能在它们身后

叫咱们就此协程做一些工作。几独简单的援助函数,使用协程可以叫咱们创建好切割的阵

咱俩可描绘一个一块的移动目标及目标位置与旋转。我们得形容一个协程的等动画是一个一定的完成百分比。然后用就半只器,
我们得以老爱地修脚论于一个单一的功能,其中她见面格外易看全切序列

采用协程,通过张其在运动,为之是要力保不见面发生另外的协程或Update()函数里改变它的位置于同一时间确保您仅仅来一个协程影响GameObject在同一时间,禁用Update()
函数 移动目标

协程动画演示

此间有一个同的一个例子等待动画部分形成

//Wait for an animation to be a certain amount complete
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();

}

You could write a coroutine to wait for an animation like this:

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);
}

资料

英文原文:http://unitygems.com/coroutines/

admin

网站地图xml地图