这个具有“产量"的函数是如何起作用的?详细工作? [英] How does this function with a "yield" work in detail?

查看:26
本文介绍了这个具有“产量"的函数是如何起作用的?详细工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I got this method (inside a Unity C# Script), but I do not understand how the "yield" part actually works.

我从 MSDN 知道该函数将返回一个 IEnumerator,我可以通过它进行迭代,但是这段代码等待 1.5 秒并且不会被迭代,因为这意味着内部创建的对象被创建了多次.这里有人可以解释一下这段代码是如何工作的吗?

I know from the MSDN that the function will return an IEnumerator which I could iterate throught, but this code waits 1,5 seconds and does not get iterated because this would mean, the objects created inside were created multiple times. Anyone here who can explain me how this code works?

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

推荐答案

正在迭代编译器为您生成的 Enumerator.一次.

The Enumerator the compiler generates for you is being iterated. Once.

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

The compiler will generate a class that implements IEnumerator, which has a MoveNext() function and a Current property. The class will have all the members required to store the state of the function between calls. The exact details can be considered "Compiler Magic".

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

The object of this generated class, will be handled and managed by the Unity3d Engine. The Unity3d Engine will call MoveNext() on each active coroutine once every frame (unless instructed otherwise).

这使 Unity3d 程序员能够编写一次播放一帧的脚本.C# 编译器魔法和 Unity3d 引擎魔法的结合产生了非常强大但易于使用的脚本.

This enabled the Unity3d Programmer to write scripts that are played out one frame at a time. A combination of C# compiler magic and Unity3d Engine magic results in very-powerful-but-easy-to-use scripting.

回答您的问题:您函数中的代码将执行一次,但会在yield return"语句处暂停.

To answer your question: the code in your function will be executed once, but it will pause at the 'yield return' statement.

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

As stated above, a special object that implements IEnumerator is created by the C# compiler.

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

On the first call to MoveNext(), your function creates an explosion and sets the current object to "new WaitForSeconds(1.5f)".

Unity3d 引擎检查此对象,发现它是特殊类WaitForSeconds"的实例,因此将枚举器放在某个等待队列中,并且在 1.5 秒过去之前不会请求第二个元素.在此期间,将渲染许多帧并播放爆炸.

The Unity3d engine inspects this object, sees it is an instance of the special class "WaitForSeconds" so puts the enumerator on some waiting queue, and won't ask for the second element until 1.5 sec have passed. In the meantime, many frames will be rendered and the explosion will be played.

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

After 1.5 sec, Unity will grap the enumerator from the queue, and call MoveNext() again. The second part of your function will execute now, but will fail to generate a second object. MoveNext() will return false to indicate it failed to get a new element, which is the signal to Unity3d to throw this enumerator away. The Garbage Collector will reclaim the memory at some point in time.

如前所述:大量的编译器和 Unity3d 魔法正在发生.只要您记住您的函数将在每个 yield return 语句的下一帧被暂停,您就会知道足以从这些特殊函数中受益.

As said: lots of compiler and Unity3d magic is going on. As long as you remember that your function will be put on hold till the next frame at each yield return statement, you'll know enough to benefit from those special functions.

这篇关于这个具有“产量"的函数是如何起作用的?详细工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆