【Unity】coroutine(コルーチン)で停止や再開を解説

サムネイル
当サイトで紹介する商品・サービス等の外部リンクは、アフィリエイト広告を含む場合があります。
スポンサーリンク
本記事を読むと以下の実行ができます

ボタンを押すと引数として指定した時間とメッセージが、コルーチンが再開、停止する。

実演

Unityのコルーチン(Coroutine)はゲーム開発において非同期処理を実現するための強力なツールです。

本記事では、コルーチンの停止や再開についてわかりやすく解説します。
Unityでスムーズにタイマー処理やループ処理をしたい方に特におすすめです。

また、指定した時間後に処理を行う方法として、
「Invoke」メソッドやAwaitがあります。

コルーチンとの違いにも触れて紹介します。

本記事は次の人におすすめ
  • コルーチンを使ったUnityでの開発に挑戦したい人
  • コルーチンの停止と再開の方法を知りたい人
  • 非同期処理を使ってスムーズなゲーム体験を実現したい人
  • Unityの基本機能からステップアップを考えている人
  • ゲームの演出やタイマーを工夫したい人
  • Invoke、Awaitとの違いを知りたい。
Udemyで学習する
スポンサーリンク

コルーチン(Coroutine)

コルーチンについて

コルーチンは、複数のフレームにまたがって実行されるタスクを扱うための方法です。
Unityだけではなく、他のプログラミング言語でも用いられる概念です。

複数フレームにわたる処理や、一定間隔で繰り返し実行する処理に適しています。
また、yield returnを使用して、任意のタイミングで一時停止や再開ができます。

Invokeよりもコード数が多くなりますが、複雑な処理ができることを示しています。

待機方法
  • yield return null
  • yield return new WaitForSeconds(seconds)
  • yield return new WaitUntil(() => condition)

yield return null

コルーチンの実行を次のフレームまで一時停止します。
Start FrameとNext Frameのログ出力は異なるフレームで行われます。

この特性を活用することで、よりダイナミックなゲームの挙動を実現できます。

例えば、プレイヤーの操作に応じてコルーチンを一時停止し、
再開することで、ゲーム内の特定の処理をコントロールできます。

using UnityEngine;
using System.Collections;

public class Sample1 : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Sample1Coroutine());
    }

    IEnumerator Sample1Coroutine()
    {
        Debug.Log("Start Frame: " + Time.frameCount);

        // 次のフレームまで待機
        yield return null;

        Debug.Log("Next Frame: " + Time.frameCount);
    }
}

yield return new WaitForSeconds(seconds)

指定した秒数だけ待機するために使用します。
Invokeに似ている処理をします。
Before WaitとAfter Waitの間に2秒の待機時間が存在します。

using UnityEngine;
using System.Collections;

public class Sample2 : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Sample2Coroutine());
    }

    IEnumerator Sample2Coroutine()
    {
        Debug.Log("Before Wait: " + Time.time);

        // 2秒待機
        yield return new WaitForSeconds(2f);

        Debug.Log("After Wait: " + Time.time);
    }
}

yield return new WaitUntil(() => condition)

指定した条件が満たされるまで待機するために使用します。
Sample3のCoroutineはisConditionMetがtrueになるまで待機します。
ChangeConditionAfterDelayコルーチンが3秒後に条件を変更します。

using UnityEngine;
using System.Collections;

public class Sample3 : MonoBehaviour
{
    private bool isConditionMet = false;

    void Start()
    {
        StartCoroutine(Sample3Coroutine());
        StartCoroutine(ChangeConditionAfterDelay());
    }

    IEnumerator Sample3Coroutine()
    {
        Debug.Log("Waiting for condition to be met...");

        // 条件が満たされるまで待機
        yield return new WaitUntil(() => isConditionMet);

        Debug.Log("Condition met!");
    }

    IEnumerator ChangeConditionAfterDelay()
    {
        // 3秒待機
        yield return new WaitForSeconds(3f);

        isConditionMet = true;
        Debug.Log("Condition changed!");
    }
}

戻り値の取得

コルーチンは戻り値を直接返すことはできませんが、IEnumeratoryield returnを組み合わせて、複数のフレームに渡る非同期処理を管理できます。

UnityではUnityWebRequestなどでサーバーからのデータを非同期で受け取るのにコルーチンを利用することがあります。

IEnumerator FetchData()
{
    UnityWebRequest request = UnityWebRequest.Get("https://example.com/data");
    yield return request.SendWebRequest();

    if (request.result == UnityWebRequest.Result.Success)
    {
        Debug.Log("Data: " + request.downloadHandler.text);
    }
    else
    {
        Debug.LogError("Failed to fetch data");
    }
}

コルーチンの注意点

コルーチンを利用する際にはいくつか注意が必要です。
コルーチンはStopCoroutine()を呼び出さない限り、
ループが続き、メモリやCPUのリソースを消費します。

そのため、必要なくなったコルーチンは必ず停止するようにしましょう。

また、似たような非同期処理としてInvokeasync/awaitもあるため、
それぞれの用途を理解して使い分けることが重要です。

Invoke

Invokeは、Unityで特定の時間が経過した後にメソッドを一度だけ実行するシンプルな方法です。

Invoke("メソッド名", 遅延時間)
Invokeの特徴
  • 単純な遅延実行: 一度だけメソッドを遅延実行
  • 使い方が簡単: メソッド名を文字列として指定し、遅延時間を引数に渡すだけ。

一例として、MessageFnメソッドを実行するようにします。
5秒後にConsoleウィンドウにテキストを表示します。

using UnityEngine;

public class Invoke_Example : MonoBehaviour
{
    void Start()
    {
        // 5秒後にMessageFnメソッドを呼び出す
        Invoke("MessageFn", 5f);
    }

    void MessageFn()
    {
        Debug.Log("5秒経過しました");
    }
}
Invokeについてまとめています。

Invokeは他にも繰り返しの処理InvokeRepeating
Invokeの処理を停止するCancelInvokeなどがあります。

操作も簡単ですが、複雑な処理には不向きです。

Await

C#のasync/awaitは非同期メソッドの実行を簡単にするものです。

Unityでは2020年以降のバージョンでTaskを使った非同期処理が可能となっており、Web API呼び出しや非同期ファイルI/Oに便利です。

private async void Start()
{
    await Task.Delay(2000);
    Debug.Log("Task Complete");
}

引数があるコルーチン

引数について

コルーチンは引数を受け取ることが可能で、これにより柔軟な処理を行えます。

例えば、何秒待つかを引数として受け取ることで、
同じコルーチンを複数の場面で使いまわすことができます。

ソースコード

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class CoroutineTest : MonoBehaviour
{
    public Button button; 
    private Coroutine routine; // コルーチンの参照を保持

    void Start()
    {
        // ボタンのクリックイベント
        button.onClick.AddListener(ToggleCoroutine);
    }

    // コルーチンの開始と停止を切り替える
    void ToggleCoroutine()
    {
        if (routine == null)
        {
            // コルーチンが動いていない場合は開始
            routine = StartCoroutine(DisplayMessage("Hello, Unity!", 1));
        }
        else
        {
           
            StopCoroutine(routine);
            routine = null;
            Debug.Log("コルーチンを停止しました");
        }
    }

    // 1秒ごとにメッセージを表示するコルーチン
    IEnumerator DisplayMessage(string message, float interval)
    {
        while (true)
        {
            Debug.Log(message);  
            yield return new WaitForSeconds(interval);  // 指定された秒数待機
        }
    }
}

UdemyでUnityを学習

Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。

\Unityの学習から収益化の方法はこちらから!/

ビックセール開催中(12月19日まで)
対象のコースが1500円から(最大95%OFF)

多彩な講座から自分に合った講座を探そう!

最大95%OFF

終了まで

時間




解説

  • 名前空間

「System.Collections」:コルーチンを使うために必要な名前空間。IEnumeratorを利用することで、コルーチンとして処理を記述できます。

「UnityEngine」:Unityの基本機能を利用するための名前空間。MonoBehaviourクラスやDebugクラスなどのUnityのコア機能が含まれています。

「UnityEngine.UI」:UI関連のクラスを利用するための名前空間。ButtonなどのUIコンポーネントを操作するために必要です。

  • フィールド(メンバ変数)

「button」:Inspectorでボタンをアタッチするための変数。ユーザーがクリックするボタンを割り当てることができます。

「routine」:コルーチンの参照を保持するための変数。コルーチンを開始・停止する際に使用され、実行中のコルーチンを追跡するために利用されます。

  • Startメソッド

ゲーム開始時に呼び出される初期化メソッド。buttonに対してクリックイベントとしてToggleCoroutineメソッドを登録しています。このメソッドにより、ボタンをクリックするたびにToggleCoroutineが呼び出されるようになります。

  • ToggleCoroutineメソッド

コルーチンの開始と停止を切り替える処理を行います。routineがnullの場合、コルーチンが動いていないことを意味し、新しいコルーチンDisplayMessageを開始します。すでにroutineが存在する場合は、実行中のコルーチンを停止し、routineをnullにして参照を解放します。

  • DisplayMessageメソッド

指定されたメッセージを指定された間隔(interval)で表示するコルーチンです。無限ループを用いてDebug.Logでメッセージを表示し、毎回yield return new WaitForSeconds(interval)で指定された時間待機します。この処理により、1秒ごとに継続的にメッセージをログに出力します。

実演

ボタンをクリックすることでコルーチンが開始され、
指定したメッセージが1秒ごとにログに出力されます。

ボタンを再度クリックすることでコルーチンが停止し、
次のボタンのクリックまでメッセージの出力が中断されます。

このように、ユーザー操作に応じてコルーチンを動的に制御することが可能です。

まとめ

この記事では、Unityのコルーチンを使って非同期処理の停止や再開について解説しました。

コルーチンは非常に便利ですが、適切に管理しないとパフォーマンスに悪影響を与えることもあります。

Invokeやasync/awaitとの違いを理解し、適材適所で使い分けましょう。

Udemyで学習する

この記事を書いた人

プロフィール

アリッシア

                 

大学4年間で何か胸を張れるスキルを身に着けたくて当サイト運営を始めました。
現在、大学院に進学するか就職するか迷いながら勉強しています。
詳しいプロフィールはこちら

Contact icon

contact

X icon

X

Instagram icon

Instagram

Note icon

Note

スポンサーリンク
Unity
フォローする
タイトルとURLをコピーしました