Unity の C# で UniTask を使う方法!導入から使い方の基本を紹介【非同期処理】

Unity の C# で UniTask を使う方法!導入から使い方の基本を紹介【非同期処理】

はじめに

近年、Unity ゲーム開発において非同期処理はますます重要になっており、非同期処理を簡単に記述できるライブラリ UniTask が注目されています。

従来の MonoBehaviour による処理では、複雑な処理になるとコードが冗長になり、デバッグも難しくなってしまうことがあります。

本記事では、コルーチンの代替としても使える非同期処理の UniTask について、導入や使い方の基本を紹介します!

UniTask とは?

UniTask は、Unity の C# 開発に特化した非同期/同期処理ライブラリです。

参考 UniTaskgithub.com

従来の Coroutineasync/await よりもパフォーマンスが高く、メモリ割り当てを減少させることができます。これにより、ゲームのフレームレートを維持しつつ、非同期処理を簡潔に記述することが可能になります。

Unity にもシームレスに統合でき、従来の MonoBehaviour と比べて以下のような利点があります。

UniTask の利点
  • コード量が大幅に削減
  • 処理の流れが分かりやすく、デバッグが容易
  • 高いパフォーマンス
  • C# の async/await をそのまま使用可能
  • Unity の公式 Asset Store で公開されている

UniTask の導入方法

UniTask の導入方法は非常に簡単です。以下の手順に従ってください。

Unityプロジェクトを開き、メニューバーから Window > Package Manager を選択します。

Unity の Package Manager の場所

+ ボタンをクリックし、Add package from git URL... を選択します。

Package Manager の git URL 入力

https://github.com/Cysharp/UniTask.git と入力し、Addをクリックします。

gitのURLを入力(UniTaskの場合)

これで UniTask がプロジェクトに追加されます。

UniTask の基本的な使い方

UniTask の名前空間を使用することで、ライブラリの機能にアクセスできるようになります。

using Cysharp.Threading.Tasks;

以下に UniTask を使って非同期処理を行うサンプルコードをいくつか紹介します。

UniTask.Delay:指定した秒数だけ待つ

UniTask.Delay を使って指定した秒数待つことができます。

using System;
using UnityEngine;
using Cysharp.Threading.Tasks;

public class Example : MonoBehaviour
{
    private async void Start()
    {
        // 1秒後にログを出力
        await UniTask.Delay(TimeSpan.FromSeconds(1f));
        Debug.Log("Hello, UniTask!");
    }
}

UniTask.DelayFrame:指定したフレーム数だけ待つ

UniTask.DelayFrame を使って指定したフレーム数待つことができます。

using System;
using UnityEngine;
using Cysharp.Threading.Tasks;

public class Example : MonoBehaviour
{
    private async void Start()
    {
        // 1フレーム後にログを出力
        await UniTask.DelayFrame(1);
        Debug.Log("Hello, UniTask!");
    }
}

UniTask.WhenAll:複数の非同期処理の並列実行

UniTask.WhenAll を使用して、複数の非同期処理を並列に実行し、すべての処理が完了するのを待つことができます。

public async UniTask LoadMultipleDataAsync()
{
    var task1 = LoadDataAsync("url1");
    var task2 = LoadDataAsync("url2");
    var task3 = LoadDataAsync("url3");

    await UniTask.WhenAll(task1, task2, task3);
    Debug.Log("すべてのデータがロードされました");
}

UniTask.WhenAny:最初に完了したタスクの結果を取得

UniTask.WhenAny を使用すると、複数の非同期タスクの中で最初に完了したタスクの結果を待つことができます。この機能は、複数の異なるソースからのデータ取得や、タイムアウトを実装する際に特に便利です。

public class Example
{
    static async UniTask Main()
    {
        // 3つの非同期処理を同時に実行
        var task1 = UniTask.Delay(1000).ContinueWith(_ => "Task 1");
        var task2 = UniTask.Delay(2000).ContinueWith(_ => "Task 2");
        var task3 = UniTask.Delay(3000).ContinueWith(_ => "Task 3");

        // 最初に完了したタスクの結果を取得
        var result = await UniTask.WhenAny(task1, task2, task3);

        Console.WriteLine(result); // "Task 1" が出力
    }
}

UniTask.WaitWhile:指定した条件が false になるまで待つ

UniTask.WaitWhile は、指定した条件が false になるまで待機するメソッドです。

非同期処理で特定の条件が満たされるまで処理を待機したい場合に便利です。

private async UniTaskVoid MyMethod()
{
    // カウントが 10 になるまで待機
    await UniTask.WaitWhile(() => count < 10);

    Debug.Log("カウントが10になりました");
}

タイムアウト付き非同期処理

非同期処理にタイムアウトを設定することも可能です。これにより、特定の時間が経過した後に処理を自動的にキャンセルさせることができます。

public async UniTask LoadDataWithTimeout(string url)
{
    // 5秒後にキャンセル
    var token = new CancellationTokenSource(TimeSpan.FromSeconds(5f)).Token;
    try
    {
        await LoadDataAsync(url, token);
        Debug.Log("データロード成功");
    }
    catch (OperationCanceledException)
    {
        Debug.Log("データロードがタイムアウトしました");
    }
}

終わりに

UniTask は Unity C# 開発における非同期プログラミングを効率化し、より高品質なゲームを制作するための強力なツールです。

UniTask の基本的な使い方をマスターすることで、ゲーム開発の生産性とパフォーマンスを大幅に向上させることが可能です。非同期処理の実装において UniTask を活用し、効率的なゲーム開発を実現しましょう。

参考リンク