【Unity】UniTaskによるasync/await を使った非同期処理

  • |
【Unity】UniTaskによるasync/await を使った非同期処理
   

少し前に身内内での勉強会で取り上げられていたのが「UniTask」です。
現状コルーチンを行っている非同期の処理を c#のasync/awaitを使って良い感じでUnityで使えるとのことで、今後新規でゲームを作成するときに利用する機会が多くなるかもしれません。
簡単ですが「UniRx」でどういったことができるのかを調べてみました。

UniTask

「UniTask」はUniRxをプロジェクトへ追加をすれば利用することができます。

導入

現状(2019/1)の最新のUnityバージョンである2018.3.0.f2を使っています。
まずはAssetStoreから「UniRx」をダウンロードし、プロジェクトへインストールします。
https://assetstore.unity.com/packages/tools/integration/unirx-reactive-extensions-for-unity-17276

namespace

UniTaskを使うときにはnamespaceを指定します。

async/await

今まではコルーチンを使っていた非同期処理がasync/awaitでも実現することができます。

非同期メソッド

頭にasyncをつけたメソッドのこと。


このメソッド内にawaitを実装することができる。
例えば1000ミリ秒待つときには「UniTask.Delay()」を使う。


こちらはコルーチンだと次のような記述で書くこともできました。


UniTaskにはdelayを含めてたくさんの便利なメソッドが良いされています。

並列実行

UniTask.WhenAll()を使えば、引数で指定した処理を並列に実行してくれます。
すべての処理が終わればその結果を受け取ることができます。

タプル

ここで見慣れないのはタプル記法で書かれた箇所です。
タプル記法について


名前のない型がタプルと呼ばれています。
UniTask.WhenAll()を使えば結果をこのタプルで取得ができます。

ラムダ式

UniTask.Run()を使うと、ラムダ式内の処理を実装できます。
戻り値も設定ができます。

遅延

UniTask.Delayを使えば、引数に指定したミリ秒処理を待機させることができます。


その他、UniTask.DelayFrameを使えば、引数に指定したフレーム分待機をさせることができます。

PlayerLoopと同期させる

PlayerLoopに合わせて、特定の処理を実行できます。


GetAsyncEventHandler

イベントの発火を待機することができます。
例えば、あるボタンが押されるまで待機するなどの処理ができます。

コルーチンを待つ

UniTaskを使えばコルーチンと併用をする機会は少ないかもしれませんが、特定のコルーチンを待つこともできます。

キャンセル処理

UniTaskの欠点はキャンセル処理が面倒くさいことです。
MonoBehaviourに依存していないので、GameObjectを削除しても消えません。
  • CancellationTokenを発行する
  • CancellationTokenSource.Cancel()を実行する
  • 非同期処理にキャンセル時の挙動を記載する

CancellationTokenを発行する

ローカル変数なりグローバル変数なりでCancellationTokenSourceを定義し、必要な非同期処理にtokenを渡して上げます。


CancellationTokenSource.Cancel()を実行する

必要なときにCancel()を呼びます。

非同期処理にキャンセル時の挙動を記載する

CancellationTokenSource.Cancel()を呼び出したときに「例外」が発生するようにします。


キャンセル時の挙動は例外を飛ばす方法以外にも、if文でも判定ができたりしますが、複雑な処理には不向きな気がします。

最後に

とりあえず、UniTaskを少し触ってみました。
コルーチンの処理に慣れていると、UniTaskによる非同期処理は複雑な感じがしました(特にキャンセル時)
色々と新しいいことができそうな予感はしているので、早く使えるようになりたい。

UniRxはこちらから入手できます。

Related Posts Plugin for WordPress, Blogger...