Unityにおける非同期タスクの実装ガイド

transform.StartTask().OnComplete(() => Debug.Log("終わり"));

を実現!!

この技術資料では、Unityでの非同期処理の管理をシンプルに行うための実装方法を説明します。本ガイドでは、非同期タスクの実行を容易にする Operation クラスを定義し、Unityのコルーチンを活用して、一定時間後に処理を実行する方法を紹介します。また、Transform クラスに対する拡張メソッドを使用して、使いやすいAPIを提供する方法も説明します。

1. Operation クラスの実装

Operation クラスは非同期処理を管理する役割を持ち、処理完了時にコールバックを呼び出します。このクラスを使うことで、非同期処理をより直感的に制御することができます。

using System;
using System.Collections;
using UnityEngine;

public class Operation
{
    private MonoBehaviour monoBehaviour;
    private Action onComplete;

    public Operation(MonoBehaviour mono)
    {
        monoBehaviour = mono;
    }

    public Operation OnComplete(Action callback)
    {
        onComplete = callback;
        return this;
    }

    public void StartOperation()
    {
        monoBehaviour.StartCoroutine(Run());
    }

    private IEnumerator Run()
    {
        Debug.Log("作業中");
        yield return new WaitForSeconds(2f);
        onComplete?.Invoke();
    }
}

2. CoroutineRunner クラス

Unityではコルーチンを使用して非同期処理を実行しますが、MonoBehaviour に依存しています。そのため、CoroutineRunner クラスを利用して、シーン内に常に存在するオブジェクトとしてコルーチンの実行環境を提供します。

using UnityEngine;

public class CoroutineRunner : MonoBehaviour
{
    private static CoroutineRunner instance;

    public static CoroutineRunner Instance
    {
        get
        {
            if (instance == null)
            {
                GameObject obj = new GameObject("CoroutineRunner");
                instance = obj.AddComponent<CoroutineRunner>();
                DontDestroyOnLoad(obj);
            }
            return instance;
        }
    }
}

3. Transform の拡張メソッド (StartTask)

Transform クラスに対して、非同期タスクを開始するための拡張メソッド StartTask を追加します。このメソッドを使うことで、任意の Transform オブジェクトから簡単に非同期タスクを開始できます。

using UnityEngine;

public static class TransformExtensions
{
    public static Operation StartTask(this Transform transform)
    {
        MonoBehaviour runner = CoroutineRunner.Instance;
        Operation operation = new Operation(runner);
        operation.StartOperation();
        return operation;
    }
}

4. 使用例 (ExampleUsage)

以下の例では、任意のGameObjectにアタッチすることでタスクを開始し、完了時にメッセージを表示します。

using UnityEngine;

public class ExampleUsage : MonoBehaviour
{
    void Start()
    {
        transform.StartTask().OnComplete(() => Debug.Log("終わり"));
    }
}

実行の流れ

  1. ExampleUsage クラスの Start メソッドで transform.StartTask() を呼び出します。
  2. CoroutineRunner を利用して Operation オブジェクトを作成し、コルーチンを開始します。
  3. コルーチン内で「作業中」とログに表示され、2秒待機後にコールバックが実行され、「終わり」とログに表示されます。

注意点とカスタマイズ

  • CoroutineRunner はシーン全体で1つのみ存在し、すべての非同期処理を管理します。
  • カスタマイズ可能: StartTask メソッドの内容を変更して、例えばファイルの読み込みやネットワークリクエストなど、より実用的な非同期処理を実装することも可能です。

結論

今回の実装により、Unityでの非同期処理をよりシンプルに管理できるようになり、コードの可読性と保守性が向上しました。Transform の拡張メソッドを使用することで、非同期タスクの実行が簡潔に記述できるようになり、開発効率が高まります。