难以使用多个产量重构IEnumerator方法

时间:2013-03-12 08:54:04

标签: c# unity3d yield-return ienumerator

我的代码的要点如下:

// Play the first beat
audio.PlayOneShot(beat);

// Show 1st heartbeat border flash
TweenAlpha.Begin(heartbeatPanel.gameObject, 0.1f, currentStress);
yield return new WaitForSeconds(0.1f);
TweenAlpha.Begin(heartbeatPanel.gameObject, 0.5f, 0);

yield return new WaitForSeconds(interval);

// Play the second beat
audio.PlayOneShot(beat);

// Show 2nd heartbeat border flash
TweenAlpha.Begin(heartbeatPanel.gameObject, 0.1f, currentStress);
yield return new WaitForSeconds(0.1f);
TweenAlpha.Begin(heartbeatPanel.gameObject, 0.5f, 0);

yield return new WaitForSeconds(interval * 2);

现在我想将上面的代码分成两个调用的单个IEnumerator方法。

这就是我提出的:

StartCoroutine(PlayBeat(currentStress, interval));
StartCoroutine(PlayBeat(currentStress, interval * 2));

// ...

IEnumerator PlayBeat(float currentStress, float interval)
{
     audio.PlayOneShot(beat);

     TweenAlpha.Begin(heartbeatPanel.gameObject, 0.1f, currentStress);
     yield return new WaitForSeconds(0.1f);
     TweenAlpha.Begin(heartbeatPanel.gameObject, 0.5f, 0);

     yield return new WaitForSeconds(interval);
}

这个问题是,不是用正确的间隔发出的节拍,而是两个节拍在同一时间响起,因为我在无限循环中有这些调用,Unity因为没有考虑间隔而崩溃。

将上面两个重复的代码块提取到单个IEnumerator方法中的最佳方法是什么?

1 个答案:

答案 0 :(得分:6)

Unity3d的Coroutines可以嵌套。要等待嵌套协程,你需要产生它。所以你的函数PlayBeat很好;你只需要以unity3d理解为“等到完成”的方式启动它。您的示例将如下所示:

yield return StartCoroutine(PlayBeat(currentStress, interval));
yield return StartCoroutine(PlayBeat(currentStress, interval * 2));

看起来与C#5的异步/等待有多么相似,这是不可思议的。在某种程度上,这并不令人惊讶,因为它们都是编译器转换的“协程”状态机 - 但它仍然可以看到相似性。