こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • UniTaskって何?
  • UniTaskを始めてみたい
  • UniTaskの便利な使い方を知りたい
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    Unityを使ってゲームを作るときにはどうしても、タイミングを調整したいという場面が登場します。

    といった感じです。

    このようなタイミング調整は 「非同期処理」 を使うと簡単に実現可能です。

    Unityが提供する非同期処理は「コルーチン」と「Task」の2種類がありますが 使い勝手はあまりよくありません。

    実はUnityの非同期処理でオススメは UniTask です。UniTaskとは Unityに最適化されたTask ということで「UniTask」 です。

    オオバはスマートフォンゲーム業界に10年以上いますが、 UniTaskなしでの開発は考えられないくらい重要な存在 になっています。

    UniTaskを使わない場合、開発期間が大幅に伸びることは間違いありません。

    この記事ではUnityを使う上で重要なUniTaskの、 インストール方法 から 基本的な使い方 までを徹底的に解説しています。

    特にUniTaskをこれから始めるという方にピッタリの記事なので、ぜひ最後まで読んでUniTaskを使えるようになってみてください。

    【注意】 本記事内のコードは初めてのUniTaskということで分かりやすさを優先してキャンセル処理を省略しています。しかしUniTaskのキャンセル処理はゲーム開発上、非常に重要です。

    UniTaskのキャンセルについては↓↓こちらの記事に詳しく記載していますので、本記事を読み終わった方は必ず読んでみてください。 知らないと大きな事故に繋がります。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    UniTaskとは?

    そもそもUniTaskとは株式会社CySharpが提供するオープンソースのライブラリです(だれでも無料で使用できるソースコード)。さまざまなUnity製タイトルで採用実績があるため非常に安心感があります。GitHubのスター(いいね数)も 6.2k と脅威の数値です。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_0

    これだけの評価を受けているライブラリですので、この記事を読んでいるあなたも 安心して 使って頂ければと思います。

    UniTaskのインストール方法

    まずはUniTaskのインストール方法を紹介します。

    お悩みさん
    お悩みさん
    UniTaskのインストールって難しそう
    オオバ
    オオバ
    めちゃくちゃ簡単!5分で終わるよ

    UniTaskのインストール方法はいくつかありますが、今回は最も簡単な Package Managerを使った方法 を紹介します。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_1
    Window > Package Manager からPackage Managerウィンドウを開きましょう。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_2
    Package Managerウィンドウの左上の「+」ボタンをクリックして、 Add package from git URL を選択。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_3
    入力フォームが表示されるので、次のURLを入力します。

    https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask  
    

    入力が終わったら 「Add」ボタンをクリック。するとUniTaskはインストールされます。

    以上で、UniTaskのインストールは完了です。簡単ですね。

    UniTaskの基本的な文法

    UniTaskをインストールしたら次は UniTaskの基本文法 について学んでいきましょう。

    まずはUniTaskを使ったソースコードを紹介します。次のコードを実行すると3秒後にオブジェクトが 左から右へ瞬間移動 します。

    transform.localPosition = new Vector3(-1f, 0, 0);  
    // 3秒間待機  
    await UniTask.Delay(3000);  
    transform.localPosition = new Vector3(1f, 0, 0);  
    

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_4

    2行目のawait UniTask.Delay(3000);によって 3秒間処理が待機 しています。

    お悩みさん
    お悩みさん
    awaitって何だろう?

    ここで登場した「await」と「UniTask.Delay」は非常に重要なキーワードです。詳しくは次の章で解説していきます。

    UniTaskの処理を待機する「await」とは

    await とはC#に実装されている機能で 非同期処理を待機する役割 を持っています。UniTaskだからawaitが使えるわけではありません。C#に元々実装されている「Task」でも同様にawaitを使えます。

    つまりUniTaskはC#に実装されているawaitを使った拡張機能ということです。

    お悩みさん
    お悩みさん
    awaitってどういう時に使ったらいいの?

    awaitをどのような時に使用するのかというと、 処理を待機したい場合 です。

    先の例では「3秒間処理を待機」しました。もし、awaitをつけなかったら3秒待機することなく、オブジェクトは右側へ瞬間移動します。

    「awaitは待機したいときに使う」 と覚えておきましょう。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_5

    任意の時間、処理を待機する「UniTask.Delay」とは

    UniTask.Delay は非常によく使われるUniTaskのメソッドです。先のawaitとセットで利用します。

    UniTask.Delayメソッドの引数には「ミリ秒」の値が入ります。例えば UniTask.Delay(1) とすると1ミリ秒待機するということです。

    お悩みさん
    お悩みさん
    ミリ秒指定って使いづらそう...

    しかしミリ秒で指定するのは正直わかりづらいですよね。そこで TimeSpan型 を使用します。TimeSpan型を使うことで「秒」や「分」といった時間単位の指定が可能です。

    具体的には次のようなコードです。

    // TimeSpanを使った3秒指定  
    await UniTask.Delay(TimeSpan.FronSeconds(3f));  
    

    3秒待機するUniTaskの処理に TimeSpan型 を利用した例です。

    TimeSpan.FromSecondsメソッドを使用することで、本来「3000」と入力してたところが「3f」と秒単位の値を入力することができました。

    オオバ
    オオバ
    感覚的で後から読みやすいのでTimeSpanの使用がオススメ

    オオバも実際の現場ではミリ秒指定を使いません。 コードの読みやすさはゲーム開発では重要 なのでTimeSpanを使って指定しています。

    UniTaskで重要な「async」キーワード

    次にawaitとセットで覚える必要のある 「async」 について学んでいきます。

    UniTaskの文法としてまず覚えておいてもらいたいこと。

    「awaitを使う場合、必ずメソッド宣言にasyncを付ける」 です。

    文字だけではわかりづらいので、次のソースコードを見ていきましょう。

    ※わかりやすくするために関数名を日本語にしています
    async UniTask 関数A()  
    {
        await 関数B();  
        // 関数Bのあとに実行したい処理  
    }
    
    UniTask 関数B(){ /*省略*/ }  
    

    上記のコードを図解すると以下のような説明になります。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_6

    つまり関数Aの中で「await」を使用する場合は、関数Aに「async」をつける必要があるということです。

    繰り返しになりますが 「awaitを使う場合、必ずメソッド宣言にasyncを付ける」 ということを覚えておきましょう。

    次の章で実際にサンプルコードや事例を通して学んでいきます。

    具体例からUniTaskの基本操作のマスター

    ここからはいくつかの具体例をもとにUniTaskの基本操作をマスターしていきましょう。

    UniTaskの基本利用3つの具体例

    ①赤色だったImageオブジェクトが2秒後に青色に変わるUniTask

    ②条件を満たすまで待機するUniTask.WaitUntilメソッド

    ③DOTweenの終了を待機して次のDOTweenを実行するUniTask

    ①赤色だったImageオブジェクトが2秒後に青色に変わるUniTask

    次のコードはImageコンポーネントの色が2秒経過で赤から青に変わるサンプルです。

    [SerializeField] private Image _image;  
    
    private async UniTask RedToBlue()  
    {
        // ① Imageオブジェクトを「赤」へ  
        _image.color = Color.red;  
        // ② 2秒間処理を待機  
        await UniTask.Delay(TimeSpan.FromSeconds(2f));  
        // ③ Imageオブジェクトを「青」へ  
        _image.color = Color.blue;  
    }
    

    たった3行で実装できます。

    実行するとこんな感じです。
    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_7

    UniTaskを使用することで、処理が行ったり来たりせず直列に上から下に処理を記述できます。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_8
    上から順に処理を読むことができるため、非常に見やすいソースコードを維持できます。

    ②条件を満たすまで待機するUniTask.WaitUntilメソッド

    UniTaskの便利なメソッドの1つ 「WaitUntil」 を紹介します。
    WaitUntilは任意の条件を満たす前で処理を待機するメソッドです。ソースコードから確認していきましょう。

    bool _isClicked;  
    
    private async UniTask CheckClick()  
    {
        await UniTask.WaitUntil(() => _isClicked);  
        Debug.Log("クリックされました");  
    }
    

    変数「_isClicked」がtrueになるまで待機するサンプルを作りました。
    「〜〜するまで待機する」といった処理はゲームを作っていると死ぬほど発生します。そんなときのレシピの1つとして覚えておくと良いでしょう。

    ゲーム開発現場ではよく登場します。

    ③DOTweenの終了を待機して次のDOTweenを実行するUniTask

    UniTaskはDOTweenとの連携も 公式にサポート されています。

    DOTweenとはソースコードでアニメーションを実装する便利なアセットです。約10年ほど長きに渡ってさまざまなタイトルで使用されています。非常に採用実績が多く安定したライブラリと言えるでしょう。

    @add{dotween, 3}

    次のコードはDOTweenをUniTaskで制御した簡単なサンプルです。

    Transformオブジェクトが1秒かけて座標 (0, 1f, 0)に移動した後、座標(1f, 0, 0) に0.5秒かけて移動します。

    private async UniTask DOTweenUniTask()  
    {
        // 1秒かけて座標 (0, 1f, 0)へ移動  
        await transform.DOLocalMove(new Vector3(0, 2f, 0), 1f);  
    
        // 0.5秒書けて(1f, 0, 0)へ移動  
        await transform.DOLocalMove(new Vector3(2f, 1f, 0), 0.5f);  
    }
    

    今回は非常にシンプルなサンプルでしたが、複雑なアニメーションを実装するときにもUniTaskは非常に強力です。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_9

    ちなみにDOTweenとUniTaskの連携には注意点があり、初期設定が必要です。何もしなければエラーが出てしまうので注意してください。初期設定から具体的な使い方について↓↓次の記事でまとめていますので、ぜひ読んでみてください。

    【知らないと損】UniTaskの超絶便利な「WhenAll」

    UniTaskの超絶便利機能「WhenAll」について紹介します。WhenAllは現場で本当によく使います。

    WhenAllは 「複数の処理が全て終了するまで待機する」 機能です。

    文字だけだとイメージがつきづらいと思いますので、次の動画を御覧ください。

    Unity-chanが全員集まったら、全員同時にジャンプをするというサンプルです。

    1. 全員が集まるまで待機
    2. 全員でジャンプ

    といった処理フローをUniTaskで実装しています。

    このように「WhenAll」を使うと、 すべての処理が終了した後に次の処理を始める のです。ソースコードは以下。

    Character[] _charas;  
    
    private async UniTask WhenAllTest()  
    {
        // ① UniTaskを格納する配列を作成  
        var tasks = new UniTask[_charas.Length];  
        for(var i = 0; i < _charas.Length; i++)  
        {
            // ② UniTaskを配列に格納  
            tasks[i] = _charas[i].Run();  
        }
        // ③ 配列内の全UniTaskの処理が終了するまで待機  
        await UniTask.WhenAll(tasks);  
    
        // ④ UniTask終了後の処理  
        foreach(var chara in _charas)  
        {
            chara.Jump();  
        }
    }
    

    ポイントは UniTask型の配列を作ってWhenAllメソッドの引数に渡しているところ です。
    すると先の動画のような複数のUniTaskを待機する処理が実装可能になります。

    現場でよく使うUniTask.WhenAllの例

    ここでは現場でよく使うWhenAllの例を紹介をします。複数のロード処理が必要な場面です。
    ここに画像A, B, Cを表示する画面があったとします。

    【超初心者向け】UniTaskのインストール方法から基本的な文法・使い方をマスターしよう_11

    つまり、画面を表示する前に画像(A, B, C)のすべてのロード完了を待機する必要があるということです。
    こんな時にWhenAllは役立ちます。

    private async UniTask ShowScreen()  
    {
        // ① 画面表示の前に画像をロード  
        await UniTask.WhenAll(  
            // ② A~Cの画像をロードする処理  
            LoadImage("A"),  
            LoadImage("B"),  
            LoadImage("C"),  
        );  
        // ③ すべての画像をロードしたら画面表示の処理開始  
        InternalShowScreen();  
    }
    
    // 画像ロードするメソッド  
    private UniTask LoadImage(string id)  
    {
        // ~~~~ 略 ~~~~  
    }
    
    

    このように WhenAll を使うと 複雑な処理を数行で実現できる のです。ぜひ使いこなせるようにしておきましょう。実際の開発現場でも高頻度で使います。

    GUI Pro - Casual Game
    GUI Pro - カジュアル ゲームは、カジュアル ゲーム用に最適化されたアセットです。漫画スタイルと直感的な GUI デザインにより、プレイヤーはより豊かなゲーム体験を得ること...
    詳しくはこちら
    GUI Pro - Casual Game
    ↑使用したアセットはこちら

    UniTaskを使う上での注意点「キャンセル処理」

    UniTaskを使う上で大事な注意点があります。それは キャンセル処理 です。キャンセル処理とは 処理の中断 のこと。

    例えば長めの演出中に画面タップで 演出をスキップ することってよくありますよね。ガチャ演出、強化演出、オープニング動画など色んなところで 演出スキップ(中断処理) が必要になります。

    今までコルーチンを使ってきた方にとってUniTaskのキャンセルはとっつきづらいものになるかもしれません。

    というのもUniTaskはコルーチンと違い GameObjectを非アクティブにしても処理が中断しない からです。開発者自身が 明示的に停止させる 必要があるためです。

    具体的には CancellationToken という中断用のトークンをUniTaskを使うたびに発行します。詳しくは次の記事にわかりやすくまとめていますので、ぜひ読んでみてください。

    まとめ : Unity開発でUniTaskを使わない理由がない

    本記事ではUniTaskのインストールから基本的な使い方までをわかりやすく紹介してきました。

    記事の内容を簡単にまとめます。

    UniTaskはUnity開発で必須

    ①UniTaskはUnityの開発現場では必須級のライブラリ

    ②UniTaskはPackage Managerを使えば簡単にインストール可能

    ③UniTaskはasync、awaitを使用

    ④UniTask.WhenAllはメチャ便利

    ⑤UniTaskのキャンセルには要注意

    こんな感じです。

    この記事だけでは正直UniTaskの魅力は10%も伝わらないかもしれません。ただ、だまされたと使ってみてください。 使えば使うほどい良いライブラリ だということがわかってきます。個人的に良いなと思うポイントは 「書き味」 です。良いライブラリは書き味が違います。

    ぜひ、UniTaskをいろいろ触ってみて書き味を感じてみてください。

    UniTaskを使ったことがない人は、ぜひ、本記事を参考にインストールしてみてください(無料なので)。使ってみて「良いな」って思ったら感謝の意を込めてGitHubのStarをクリックしましょう。

    おそらく、オオバは今後もUniTaskを使い続けていくと思いますので、便利な使い方や落とし穴はまた別の記事で紹介していこうと思います。

    より詳しくUniTaskを勉強したいという方はこちらの書籍もオススメです。

    UniRx/UniTask完全理解 より高度なUnity C#プログラミング
    UniRx/UniTaskライブラリを学んでつよつよプログラマになる!UnityにおけるC#プログラミングをある程度習得している人を対象として、UniRx/UniTaskの活用方法...
    詳しくはこちら
    UniRx/UniTask完全理解 より高度なUnity C#プログラミング

    「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
    ぜひチャンネル登録をお願いします!

    最後まで読んでいただきありがとうございました!
    すばらしいUniTaskライフをお過ごしください。

    記事内で使用したアセット
    オススメ記事
    検証環境
    参考サイト