コルーチン内のループ
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エディターがフリーズします。
チャレンジ
簡単跳ね橋が往復するようにRideを書きましょう。
Vector3 up = down + Vector3.up * height;を設定します。while (transform.position != up)の間、Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime)で移動させ、yield return null;を実行します。Openをログに出力し、その後yield return new WaitForSeconds(1f);を実行します。- 同じ方法で
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プレイグラウンド