LoginSignup
0
1

UnityのAwaitableを使った時に非同期で使えないAPIを使いたいときのメモ

Posted at

初めに

Unity 2023.1 から公式でAwaitableという非同期向けのクラスが用意されました。
今回はこれを使うにあたりUnityのAPI使えない問題に遭遇したので対処のメモです。

先に結論

Awaitable.MainThreadAsyncを使ってメインスレッドでUnityのAPIを使い、
Awaitable.MainThreadAsyncを使ってバックグラウンドスレッドで処理を行う

参考: https://docs.unity3d.com/2023.2/Documentation/Manual/AwaitSupport.html

遭遇した事象

例えば以下のコードだと2か所でその処理、バックグラウンドスレッドで処理できないよと怒られます。

await Task.Delay(0); // ここでは他の非同期処理 (Delay()で代用)

// 画像を作成して保存したい
var imagePath = Path.Combine(Application.persistentDataPath, fileName); // ここでNG ・・・1
var texture = new Texture2D();
await File.WriteAllBytesAsync(imagePath, texture.EncodeToPNG()); // ここでNG ・・・2

なぜ怒られるかというと、1つ目はApplication.persistentDataPathが、2つ目はtexture.EncodeToPNG()がそれぞれ怒られてしまいます。
文字列の取得だけに怒られるなんて...
エンコードなんていう重い処理をバックグラウンドスレッドで実行させてくれないなんて...

対策

さて、ファイル書き込みを含む重めになりそうな処理をするのであれば非同期にはしたいです。
ドキュメントをあさってみるとUnity 2023.2以降のEnglishページに解決策が書いてありました。
結論の通りに修正すると以下のコードになります。

await Task.Delay(0); // ここでは他の非同期処理 (Delay()で代用)

// 画像を作成して保存したい
await Awaitable.MainThreadAsync(); // UnityのAPIをメインスレッドで実行する
var imagePath = Path.Combine(Application.persistentDataPath, fileName);
var texture = new Texture2D();
var pngData = texture.EncodeToPNG();
await Awaitable.BackgroundThreadAsync(); // ファイル書き込みはバックグラウンドスレッドで実行する
await File.WriteAllBytesAsync(imagePath, pngData);

これで問題なく動くようになりました!
ポイントとしては

  • バックグラウンドで処理したい場合はawait Awaitable.BackgroundThreadAsync()する
  • メインスレッドで処理したい場合はawait Awaitable.MainThreadAsync()する
  • 2024/2/28現在は2023.2以降の英語マニュアルでないとAwaitableの解説がない

というところですね。

最後に

それメインスレッドでなくても・・・と思うところはありましたが、基本的に非同期は複雑性と危険性が伴うのも事実なのでマニュアルに沿ってメインスレッドとバックグラウンドスレッドを切り替えていけばよさそうですね!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1