コルーチンの停止
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 25/63。
StartCoroutineはCoroutineを返します。これは、開始したコルーチンへのハンドルです。これをフィールドに保存すると、StopCoroutine(handle)で、そのコルーチンを一時停止している位置で停止できます。つまり、yieldの後の行は実行されません。StopAllCoroutines()は、そのスクリプトが開始したすべてのコルーチンを停止します。スペースキーで、このアラームをオン・オフします。
Coroutine beeping;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (beeping == null)
{
beeping = StartCoroutine(Beep());
}
else
{
StopCoroutine(beeping);
beeping = null;
}
}
}
IEnumerator Beep()
{
while (true)
{
Debug.Log("Beep");
yield return new WaitForSeconds(1f);
}
}コルーチンが停止してもフィールドは自動的に空にならないため、アラーム側でフィールドをnullに戻します。すると次にスペースキーを押したとき、実行中のコルーチンがないことがわかります。一見正しそうな2つの方法は、うまくいきません。StopCoroutine(Beep())はBeep()を再び呼び出すため、新しく、まだ開始されていないコルーチンを作成してそれを停止するだけで、アラームは鳴り続けます。また、enabled = falseはスクリプトのUpdate()を無効にしますが、コルーチンはそのまま実行されます。コルーチンは、ハンドルを使って停止するか、StopAllCoroutines()を呼び出したとき、最後の行に到達したとき、またはSetActive(false)によってGameObjectが非アクティブ化されたとき、あるいは破棄されたときに終了します。
チャレンジ
簡単スペースキーでBombの導火線に火がつきます。FuseコルーチンはFuse litをログに出力し、fuseTime秒(3秒)待ってから、Boomをログに出力し、爆弾を破棄します。クリックすると導火線を消せるはずですが、スクリプトがオフになり、爆弾はそのまま爆発してしまいます。消火処理を修正しましょう。
- 導火線に火がついている間にクリックすると、導火線を消し、
Defusedをログに出力します。爆弾は残ります。 - その後、スペースキーでもう一度導火線に火をつけられます。そのときはクリックしなければ、3秒後に爆弾が爆発します。
Playを押し、導火線に火をつけてクリックし、コンソールを確認してから、Checkを押してください。
自分で試してみよう
using System.Collections;
using UnityEngine;
public class Bomb : MonoBehaviour
{
public float fuseTime = 3f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(Fuse());
}
if (Input.GetMouseButtonDown(0))
{
enabled = false;
Debug.Log("Defused");
}
}
IEnumerator Fuse()
{
Debug.Log("Fuse lit");
yield return new WaitForSeconds(fuseTime);
Debug.Log("Boom");
Destroy(gameObject);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。