[unity]コルーチンの停止、一時停止(ポーズ)、再開

unity でタスク処理といえば真っ先に浮かぶコルーチンですが、実行させっぱなしならともかく、丁寧に状態管理したい場合、色々と手続きが必要です。

コルーチンの作成、実行

まずは単純なコルーチンの使い方から。

using System.Collections;
using UnityEngine;

public class Sample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(testRoutine());
    }

    IEnumerator testRoutine()
    {
        int a = 0;

        while (true)
        {
            Debug.Log($"a: {a++}");

            yield return null;
        }
    }
}

特定のコルーチンだけ停止

全てのコルーチンを停止する場合 StopAllCoroutines() を使うこともできますが、特定のコルーチンのみ止めたい場合は、以下のようなコードにします。

StartCoroutine の戻り値を取っておくのがポイントです。

サンプルでは「1」キーを押すとコルーチンが停止するようになっています。

using System.Collections;
using UnityEngine;

public class Sample3 : MonoBehaviour
{
    Coroutine coroutine;

    void Start()
    {
        coroutine = StartCoroutine(testRoutine());
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1) == true)
        {
            StopCoroutine(coroutine);
        }
    }

    IEnumerator testRoutine()
    {
        int a = 0;

        while (true)
        {
            Debug.Log($"a: {a++}");

            yield return null;
        }
    }
}

コルーチンの一時停止、再開

先ほどの方法で停止した後、元の位置からコルーチンを再開することはできません。
一時停止、再開を可能にしたい場合、少し書式が異なります。

Coroutine ではなく、IEnumerator を使い、Start・Stop を行います。

「1」キーで一時停止、「2」キーで再開を行います。

using System.Collections;
using UnityEngine;

public class Sample : MonoBehaviour
{
    IEnumerator routine;

    void Start()
    {
        routine = testRoutine();
        StartCoroutine(routine);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1) == true)
        {
            StopCoroutine(routine);
        }
        if (Input.GetKeyDown(KeyCode.Alpha2) == true)
        {
            StartCoroutine(routine);
        }
    }

    IEnumerator testRoutine()
    {
        int a = 0;

        while (true)
        {
            Debug.Log($"a: {a++}");

            yield return null;
        }
    }
}

StopCoroutine((Coroutine)coroutine) しても、StartCoroutine((Ienumerator)routine) で再開できちゃいます。

GameObject.SetActive(false) でコルーチンが停止してしまう時は……

GameObject を非アクティブにすると、こっそりコルーチンが停止します。
非アクティブからアクティブに戻した時、コルーチンも動き出して欲しい……。

そこで、IEnumerator の再開機能を上手く使います。

using System.Collections;
using UnityEngine;

public class Sample : MonoBehaviour
{
    IEnumerator routine;

    void Start()
    {
        routine = testRoutine();
        StartCoroutine(routine);
    }

    void OnEnable()
    {
        StartCoroutine(routine);
    }

    IEnumerator testRoutine()
    {
        int a = 0;

        while (true)
        {
            Debug.Log($"a: {a++}");

            yield return null;
        }
    }
}

OnEnable に StartCoroutine を仕込んでおくことで、GameObject アクティブと同時にコルーチンの動作が再開します。

なお、非アクティブでもコルーチンを動かしたい場合は別のアクティブな GameObject に委任するような方法を取りましょう。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA