具有"产量"的功能如何正常工作?

Jul*_*s F 13 c# yield yield-return unity-game-engine

我得到了这个方法(在Unity C#Script中),但我不明白"yield"部分是如何工作的.

我从MSDN知道该函数将返回一个我可以迭代的IEnumerator,但是这段代码等待了1.5秒并且没有迭代,因为这意味着,内部创建的对象被多次创建.这里的任何人都可以解释一下这段代码的工作原理

IEnumerator DestroyShip()
{
    // create new gameobject
    Instantiate(ExplosionPrefab, transform.position, transform.rotation);
    // make current gameobject invisible
    gameObject.renderer.enabled = false;
    // set new position for the current gameobject
    transform.position = new Vector3(0f, transform.position.y, transform.position.z);
    // wait for 1,5 seconds 
    yield return new WaitForSeconds(1.5f);
    // make the current gameobject visible again
    gameObject.renderer.enabled = true;
}
Run Code Online (Sandbox Code Playgroud)

Sjo*_*erd 27

编译器为您生成的枚举器正在迭代.一旦.

编译器将生成一个实现IEnumerator的类,该类具有MoveNext()函数和Current属性.该类将具有在调用之间存储函数状态所需的所有成员.确切的细节可以被认为是"Compiler Magic".

此生成的类的对象将由Unity3d Engine处理和管理.Unity3d引擎将每帧调用每个活动协程上的MoveNext()(除非另有说明).

这使Unity3d Programmer能够编写一次一帧播放的脚本.C#编译魔术和Unity3d Engine魔术的结合使得脚本功能非常强大但易于使用.

回答你的问题:函数中的代码将被执行一次,但它会在'yield return'语句中暂停.

如上所述,实现IEnumerator的特殊对象是由C#编译器创建的.

在第一次调用MoveNext()时,您的函数会创建爆炸并将当前对象设置为"new WaitForSeconds(1.5f)".

Unity3d引擎检查此对象,看到它是特殊类"WaitForSeconds"的实例,因此将枚举器放在某个等待队列上,并且在1.5秒之前不会要求第二个元素.与此同时,将渲染许多帧并播放爆炸.

1.5秒后,Unity将从队列中抓取枚举器,并再次调用MoveNext().函数的第二部分现在将执行,但无法生成第二个对象.MoveNext()将返回false以指示它无法获取新元素,这是Unity3d向该枚举器抛出的信号.垃圾收集器将在某个时间点回收内存.

如上所述:许多编译器和Unity3d魔法正在进行中.只要你记得你的函数将被保留到每个yield return语句的下一帧,你就会知道这些特殊函数会受益.


Pao*_*sco 5

如果yield使用一次,就好像你正在返回一个带有一个元素的IEnumerator,这就是为什么你会得到它不会迭代的印象.

这是yield关键字的一个相当奇怪的用法,很难理解为什么它被实现,所以没有看到整个上下文.