UniTaskとコルーチンの違いと使い方

Unity

現在のプロジェクトのコルーチン箇所をUniTaskに置き換えようと思い色々調べたので備忘録

メリット・デメリット

メリット

  • 戻り値が使える
  • 標準で動作中の関数を一覧出来るツール(UniTask Tracker)が付いている
  • Update以外のタイミングで待てる

デメリット

  • シーン遷移やGameObjectが削除されたりしても止まらず、途中で処理を止めるためのハンドリングが必要

基本文法

コルーチンの場合

UniTask

ちょっと応用

関数がいろんなオブジェクトについている場合

コルーチンの場合

適当な例なので処理が変かも

UniTaskの場合

並列処理の例

複数の非同期タスクを並列で実行したい場合は、UniTask.WhenAllやUniTask.WhenAnyを使用すると簡単に実現できます。

サンプルコード: 並列実行 (全タスク完了を待つ場合)

並列処理の活用シーン

  • キャラクターアニメーションやエフェクトを同時に再生する
  • サーバーリクエストを複数並行して送信する
  • バトル中の複数の非同期ロジックを同時進行する

オブジェクトの破棄に対応するための方法と設計方針

メリデメで記載した通りコルーチンと違いオブジェクトが消えても処理が継続されるので明確にキャンセル処理が必要

シーン制御クラスや呼び出す側の関数でCancellationTokenを取得して利用することで対処できる

UniTaskの既存関数の場合

UniTask.Yieldawait UniTask.DelayなどのUniTask側が用意している関数は引数にCancellationTokenを渡すといい感じにキャンセルを行ってくれる。

独自関数の場合

独自関数の場合はtry/catchで中断処理が必要

サンプル

キャンセル状態をポーリングするか、例外で中断するかはケースバイケース

  • 無限ループ処理では、ct.ThrowIfCancellationRequested()で中断する方が明示的。
  • 短い処理やチェック頻度が少ない場合はct.IsCancellationRequestedでOK。

共通で使用する末端の関数はCancellationTokenを受け取ってcatchした場合はthrowするようにしたほうがいいかも。

catchだけしてthrowしないと当然ながら次の処理に行ってしまう。

DontDestroyやシングルトンなオブジェクトの場合

こちらも他関数と同様に呼び出す関数側からCancellationTokenをもらってキャンセルを行う感じでいいかも

シーンごとにCancellationTokenSourceを持つ場合

DontDestroyOnLoadなオブジェクトやシングルトンなオブジェクトに専用のCancellationTokenSourceを持たせる

UniTaskのなかでコルーチン関数を呼ぶ方法

ToUniTaskを使用することでUniTaskの関数内でコルーチン関数を実行できます。
CancellationTokenをToUniTaskに引数として渡すことでキャンセル処理もできます。

コルーチンの中でUniTask関数を呼ぶ場合

コルーチンの中でUniTask関数を呼ぶ場合はToCoroutine()を使用することで呼び出すことができます。

コメント