ロバメモ - 素人のUnity覚書と奮闘記

素人のUnity覚書と奮闘記

コルーチン 中断って何を?

前記事からの続き。
robamemo.hatenablog.com

おさらい

yield return ナンチャラ =ナンチャラとタイミング合わせるからちょっと中断するねという意味。
さて、この中断って、何を中断しているの?って話。

◯秒待って処理を再開したい

例えば、”◯秒待って処理を再開したい” というのは、コルーチンを使う。

yield return new WaitForSeconds(秒数);

サンプルコード

Startからの経過時間を図り(seconds)5秒毎にDebug.Logでsecondsの値を出力する。
Mathf.Floor()は、四捨五入。

float seconds = 0f;

void Start ()
{
    StartCoroutine (Routine ());
}
    

void Update ()
{
    seconds += Time.deltaTime;
}

IEnumerator Routine ()
{
    while(true){
        yield return new WaitForSeconds (5);
        Debug.Log (Mathf.Floor (seconds) + "秒経ったよ");
    }
}

出力結果

f:id:nico-taniku:20170912165916p:plain:w300
なんだろう?出力の文字が「よ」とか小さめでギャルっぽいw

中断て何を?

上のコード、経過秒数をカウントするのにUpdate使ってるけど、コルーチンでもできるんじゃない?
こんな感じで書いても、同じ結果になるよね。

float seconds = 0f;

void Start ()
{
    StartCoroutine (Counter ());
    StartCoroutine (Routine ());
}

IEnumerator Counter ()
{
    while (true) {
        seconds += Time.deltaTime;
        yield return null;
    }
}

IEnumerator Routine ()
{
    while (true) {
        yield return new WaitForSeconds (5);
        Debug.Log (Mathf.Floor (seconds) + "秒経ったよ");
    }   
}

でもコルーチンを並べて同時に開始するなら、1つでいいんじゃない?って思っちゃう。
で、こんなことをしてみると

IEnumerator Routine ()
{
    while (true) {
        seconds += Time.deltaTime;
        yield return null;
    }

    while (true) {
        yield return new WaitForSeconds (5);
        Debug.Log (Mathf.Floor (seconds) + "秒経ったよ");
    }   
}

待てど暮らせど、出力されない。
なぜなら、
(1)yield return nullで、Routine()自体が中断
(2)yield return nullが書かれたところ(while内)から再開
(3)1つ目のwhile内をぐるぐるしてるだけ。

試しに、secondsを出力してみると、0〜カウントアップされた数値が表示されるので、1つの目whileは実行されているのがわかる。

   while (true) {
        seconds += Time.deltaTime;
        yield return null;
        Debug.Log (Mathf.Floor (seconds));  //コレ追加
    }

コルーチン自体が中断されるので、2つ目のwhileが実行されない。

ちょっと落とし穴になりそうな感じ。

以上。