コルーチンの停止
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 26/71。
StartCoroutineはCoroutineを返します。これは、開始したコルーチンへのハンドルです。これをフィールドに保持すると、StopCoroutine(handle)は、そのコルーチンが一時停止している箇所で停止させます。そのyieldの後の行は実行されません。StopAllCoroutines()は、スクリプトが開始したすべてのコルーチンを停止します。Spaceキーでこのアラームのオンとオフを切り替えます。
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に戻します。そうすれば、次にSpaceキーを押したとき、実行中のコルーチンがないことがわかります。一見正しそうな方法が2つありますが、どちらも機能しません。StopCoroutine(Beep())はBeep()を再度呼び出します。これによって新しい未開始のコルーチンが作られ、そのコルーチンが停止されるため、アラームは鳴り続けます。また、enabled = falseにするとスクリプトのUpdate()はオフになりますが、コルーチンはそのまま続行します。コルーチンは、ハンドルを使って停止されたとき、またはStopAllCoroutines()によって停止されたとき、最後の行に到達したとき、あるいはSetActive(false)でGameObjectが非アクティブ化されたとき、または破棄されたときに終了します。
チャレンジ
簡単スクリプトを無効にせず、クリックで爆弾の起爆を解除できるようにしましょう。
- フィールド
Coroutine fuse;を追加します。Spaceキーを押したとき、fuse = StartCoroutine(Fuse());を設定します。 - クリック時に
enabled = false;を置き換えます。fuse != nullの場合は、StopCoroutine(fuse);を呼び出し、fuse = null;を設定して、Defusedをログに出力します。
「プレイ」を押し、Spaceキーを押してからクリックします。ConsoleにDefusedと表示され、爆弾はそのまま残ります。その後、「確認」を押します。
自分で試してみよう
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);
}
}
物理演算とゲームプレイのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド