Menu
CoddyTech

コルーチン内のループ

CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 25/71。

内部にyield returnがあるループは、各反復で次の反復の前に一時停止するため、複数のフレームにわたって実行されます。WaitForSecondsを使うと、ループは一定の間隔で処理を繰り返します。このサイレンは3回点滅します。

IEnumerator Flash()
{
    for (int i = 0; i < 3; i++)
    {
        lamp.enabled = true;
        yield return new WaitForSeconds(0.2f);
        lamp.enabled = false;
        yield return new WaitForSeconds(0.2f);
    }
}

yield return nullを使うと、条件が満たされるまでループはフレームごとに少しずつ処理を行います。これによってコルーチンは何かをアニメーションさせます。この風船は、スケールが1の状態から、スケールが2になるまで毎秒0.5ずつ大きくなり、その後、次のメッセージを出力します。

IEnumerator Inflate()
{
    while (transform.localScale.x < 2f)
    {
        transform.localScale += Vector3.one * 0.5f * Time.deltaTime;
        yield return null;
    }
    Debug.Log("Full");
}

ここでのTime.deltaTimeの働きはUpdate()の場合と同じです。コルーチンはフレームごとに再開し、ループの後の行はループが終わったときにだけ実行されます。yieldがなければ、ループ全体が1つのフレーム内で実行され、風船は一気に膨らみます。コルーチン内でのwhile (true)ループは、毎回の反復でyieldする限り問題ありません。yieldがなければ、フレームを返さず、Unityエディターがフリーズします。

challenge icon

チャレンジ

簡単

跳ね橋が往復するようにRideを書きましょう。

  1. Vector3 up = down + Vector3.up * height;を設定します。while (transform.position != up)の間、Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime)で移動させ、yield return null;を実行します。
  2. Openをログに出力し、その後yield return new WaitForSeconds(1f);を実行します。
  3. 同じ方法でdownまで戻し、その後Closedをログに出力します。

「プレイ」を押してからSpaceキーを押します。門が上がり、待機してから閉じます。その後、「確認」を押します。

自分で試してみよう

using System.Collections;
using UnityEngine;

public class Portcullis : MonoBehaviour
{
    public float speed = 1.5f;
    public float height = 3f;
    Vector3 down;

    void Start()
    {
        down = transform.position;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Ride());
        }
    }

    IEnumerator Ride()
    {
        // speed の速さで height 単位上昇して Open をログに出力し、1 秒間そのままにしてから下降し、Closed をログに出力する
        yield return null;
    }
}

物理演算とゲームプレイのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド