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 に委任するような方法を取りましょう。