2013-03-12 13 views
5

Istotą mojego kodu jest następujący:Mając kłopoty refactoring metodę IEnumerator z wieloma rentowności

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

Teraz chcę podzielić powyższy kod do jednej metody IEnumerator z 2 połączeniami.

To właśnie wymyśliłem:

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

Problem polega na tym, że zamiast bije brzmiące z ich prawidłowym odstępie oba bity brzmiały w tym samym czasie i dlatego mam te połączenia w nieskończona pętla, Unity rozbił się, ponieważ interwały nie są brane pod uwagę.

Jaki jest najlepszy sposób na wyodrębnienie moich dwóch powtarzających się bloków kodu powyżej w jednej metodzie IEnumerator?

+0

Twój bieżący kod wygląda dobrze (przynajmniej bez widoku "StartCoroutine") - na czym polega problem? –

+1

Czy możesz opisać problem bardziej niż "to nie działa"? – ChrisF

+0

Czy mam rację, że słyszysz dwa uderzenia naraz? – Kay

Odpowiedz

6

Coroutines Unity3d można zagnieżdżać. Aby poczekać na zagnieżdżonego coroutine, musisz go wydać. Więc twoja funkcja PlayBeat jest w porządku; wystarczy uruchomić go w taki sposób, że unity3d rozumie, że oznacza "poczekaj, aż do zakończenia". Twój przykład będzie wyglądał następująco:

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

To niesamowite, jak podobne to wygląda na asynchroniczne/czekające C# 5. Na pewnym poziomie nie jest to zaskakujące, ponieważ są one zarówno przekształconymi w kompilator "statystykami" koroutynowymi - ale wciąż jest to łatwe do zobaczenia podobieństwa.

+0

+1 Właśnie wypróbowałeś to i działa bezbłędnie. –