5

私のコードの要点は次のとおりです。

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

ここで、上記のコードを 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 がクラッシュしたことです。

上記のコードの 2 つの繰り返しブロックを単一の IEnumerator メソッドに抽出する最良の方法は何ですか?

4

1 に答える 1

6

Unity3d のコルーチンはネストできます。ネストされたコルーチンを待つには、それを譲る必要があります。あなたの機能PlayBeatは問題ありません。unity3d が「完了するまで待つ」という意味を理解する方法で開始する必要があります。例は次のようになります。

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

それが C# 5 の async/await にどれほど似ているかは驚くべきことです。どちらもコンパイラによって変換された「コルーチン」ステートマシンであるため、あるレベルではこれは驚くべきことではありませんが、それでも類似性を確認することはできます。

于 2013-03-12T09:06:58.237 に答える