[Unity]コルーチンを再実行したら途中から実行されてしまった件:コルーチンの初期化について

Unity

結論:IEnumerator変数に対象のコルーチン関数を再設定しないといけなかった

まずは簡単に結論からです

IEnumerator型の変数を定義して対象のコルーチンを再度格納しないといけなかったです

自分がやってしまったダメなやりかた

以下のようなスクリプトを実行していました

画面上でマウスをクリックするとコルーチンが実行して

もう一度マウスをクリックするとコルーチンが停止する。

で、更にマウスクリックでコルーチンが実行される、というものです

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    private int count;
    private bool flg;
    private IEnumerator CoroutineVariable;

    // Start is called before the first frame update
    void Start()
    {
        count = 0;
        flg = true;
        CoroutineVariable = testCoroutine();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (flg)
            {
                flg = false;
                count++;
                StartCoroutine(CoroutineVariable);
            } else
            {
                flg = true;
                StopCoroutine(CoroutineVariable);
            }
        }
        
    }

    private IEnumerator testCoroutine()
    {
        Debug.Log("count = " + count  + ", test 1");
        yield return new WaitForSeconds(1f);
        Debug.Log("count = " + count + ", test 2");
        yield return new WaitForSeconds(1f);
        Debug.Log("count = " + count + ", test 3");
        yield return new WaitForSeconds(1f);
    }
}

さぁ、これでゲーム実行してみよう!

ってことでやってみたら想定と違う動作をしていました。

上記スクリプトをGameObjectにアタッチして実行してみたのが以下です

コンソール画面をみてみてください

三回目にクリックしたとき、コンソールに「count = 2, test 3」と表示されています

つまり、二回目にStartCoroutineでコルーチンを実行したとき

前回実行中に停止した箇所の続きから処理が実行されているわけです

私の想定では、二回目にコルーチンを実行した時は

もう一度、最初の処理から実行されるものだと思い込んでいましたが、

実際は違ったらしいです、なんてこったい!

本当はこうすればよかった

じゃぁどうすればいいの?って話ですが

以下のようにIEnumerator変数に対象のコルーチンを再設定すれば

想定通りに動作してくれました

27行目で変数を初期化しているみたいな感じです

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    private int count;
    private bool flg;
    private IEnumerator CoroutineVariable;

    // Start is called before the first frame update
    void Start()
    {
        count = 0;
        flg = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (flg)
            {
                flg = false;
                count++;
                CoroutineVariable = testCoroutine();
                StartCoroutine(CoroutineVariable);
            } else
            {
                flg = true;
                StopCoroutine(CoroutineVariable);
            }
        }
        
    }

    private IEnumerator testCoroutine()
    {
        Debug.Log("count = " + count  + ", test 1");
        yield return new WaitForSeconds(1f);
        Debug.Log("count = " + count + ", test 2");
        yield return new WaitForSeconds(1f);
        Debug.Log("count = " + count + ", test 3");
        yield return new WaitForSeconds(1f);
    }
}

このスクリプトを実行してみたのが以下です

想定通りの動作になってくれました!

おわりに

StopCoroutineを呼び出した時には

実行中のその瞬間の処理行でコルーチンが停止するらしく

さらに再度StartCoroutineでコルーチンを実行すると

停止していた行の次から実行されるみたいです

そうさせたくない場合は、もう一度コルーチンを変数に定義してあげて

変数を初期化する必要があるようでした!

タイトルとURLをコピーしました