Unity入門

【Unity】Coroutineの使い方・停止・終了の基本、yieldの使い方も徹底解説

Unityで「一定時間待って処理を実行」「フェードイン・フェードアウト」「非同期で処理を行う」などの機能を実現するとき、Coroutine(コルーチン)を活用すると便利です。

  • 敵を3秒後にスポーンさせたい!
  • BGMをフェードイン・フェードアウトしたい!
  • 重い処理を分割して、フレームレートの低下を防ぎたい!

Coroutine(コルーチン)を使えば、Update()では難しい「時間を待つ処理」や「非同期処理」を簡単に実装できます!
この記事では、Coroutine(コルーチン)の基本から、実践的な応用例、最適化のポイントまで詳しく解説します!

この記事でわかること

  • Coroutine(コルーチン)の基本的な使い方
  • 時間経過処理(フェードイン・フェードアウト・スポーン管理)
  • 重い処理を分割し、パフォーマンスを最適化する
  • Coroutine(コルーチン)を途中で停止する方法

Coroutine(コルーチン)の使い方

Coroutine(コルーチン)の概要

Coroutine(コルーチン)とは、処理の途中で一時停止し、一定時間後に再開できる仕組みです。
void(戻り値なし)とは異なり、IEnumeratorを返す関数を使います。

時間経過を待って処理を実行できる!
Update()を使わずに、処理の流れを管理できる!(非同期処理)
重い処理を少しずつ、フレームレート低下を防ぐ!

※ 同期・非同期Unityライフサイクルについては下記のサイトを参考にしてください。

Coroutine(コルーチン)のスクリプト書き方(yield、wait)

yield return new WaitForSeconds(秒数)を使うと、一定時間後に処理を実行
できる

using UnityEngine;
using System.Collections;

//3秒後に処理を実行する
public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(ExampleCoroutine());
    }

    IEnumerator ExampleCoroutine()
    {
        Debug.Log("処理開始");
        yield return new WaitForSeconds(3); // 3秒待つ
        Debug.Log("3秒後に処理実行");
    }
}

Coroutine(コルーチン)の実践例

フェードイン・フェードアウト(yield return null)

Coroutine(コルーチン)を使うと、スムーズなフェードイン・アウトを実現できます。
yield return null;を使うと、毎フレーム処理が実行される!
canvasGroup.alphaを少しずつ減らすことで、緩やかなフェードアウトができる!

using UnityEngine;
using System.Collections;

//フェードアウト(徐々に透明にする)
public class FadeEffect : MonoBehaviour
{
    public CanvasGroup canvasGroup;

    public void StartFadeOut()
    {
        StartCoroutine(FadeOut());
    }

    IEnumerator FadeOut()
    {
        while (canvasGroup.alpha > 0)
        {
            canvasGroup.alpha -= Time.deltaTime / 2; // 2秒かけてフェードアウト
            yield return null;
        }
    }
}

一定間隔で敵をスポーン

while (true)で、永続的に処理を続けられる!
WaitForSeconds(5)で、5秒ごとに敵をスポーン!

using UnityEngine;
using System.Collections;

//5秒ごとに敵を生成
public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public Transform spawnPoint;

    void Start()
    {
        StartCoroutine(SpawnEnemies());
    }

    IEnumerator SpawnEnemies()
    {
        while (true)
        {
            Instantiate(enemyPrefab, spawnPoint.position, Quaternion.identity);
            yield return new WaitForSeconds(5);
        }
    }
}

Coroutine(コルーチン)の停止・終了

yield breakで途中終了

yield break;を使うと、強制的にコルーチンを終了できる!

//条件を満たしたら即終了
IEnumerator FadeOut()
{
    while (true)
    {
        if (canvasGroup.alpha <= 0)
        {
            yield break; // コルーチンを即終了
        }
        canvasGroup.alpha -= Time.deltaTime / 2;
        yield return null;
    }
}

Coroutine(コルーチン)のパフォーマンス最適化

Wait For Secondsの最適化

WaitForSeconds()は毎回新しいオブジェクトを生成するため、メモリ負荷を軽減するためにWaitForSecondsRealtime()使うと良い

private WaitForSecondsRealtime waitTime = new WaitForSecondsRealtime(1.0f);

IEnumerator ExampleCoroutine()
{
    yield return waitTime; // GCの負担を減らす
    Debug.Log("1秒後の処理");
}

IEnumeratorのキャッシュ

IEnumeratorをキャッシュすると、余計なメモリ確保を防ぐ!

private IEnumerator fadeOutCoroutine;

void Start()
{
    fadeOutCoroutine = FadeOut();
}
void StartFade()
{
    StartCoroutine(fadeOutCoroutine);
}

まとめ

Coroutine(コルーチン)を使うと、一定時間待機処理や非同期処理が簡単に実装できる!
yield return new WaitForSeconds(秒数)を使って、時間経過後に処理を実行可能!
yield break;で途中停止もできる!
最適化を意識して、メモリ負荷を減らすことが重要!