unity-unitask-design について
UniTask 2.5.10を使うUnity開発者向けの非同期処理リファレンスです。タイミング、キャンセル、合成、Unity非同期操作との変換を扱い、実装やレビューで動作を確認できるソース位置を示します。
主な機能
- 01UniTaskと非同期メソッドのルール
- 02PlayerLoopTimingと遅延動作
- 03CancellationTokenの処理
- 04WhenAllやWhenAnyによる合成
- 05Unity非同期操作向けアダプター
活用シーン
- 01UniTask非同期メソッドの作成・レビュー
- 02PlayerLoopTimingの選択とキャンセル処理
- 03複数の非同期処理の合成
- 04Unity非同期操作のUniTaskへの変換
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ besty0728/ unity-skills --skill unity-unitask-designインストール後、Claude Code で/unity-unitask-designを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
ASYNCENUMERABLE.mdBASICS.mdCANCELLATION.mdCOMPOSITION.mdCONVERSION.mdPITFALLS.mdPLAYERLOOP.mdTRIGGERS.md詳細
このモジュールのスキルを呼び出す前に: 名前や説明から推測したパラメーターを指定してスキルを呼び出そうとしている場合は、いったん停止してください。まずこのファイルを読むか、
GET /skills/recommend?includeSchema=trueでスキーマを取得してください。recommend/schema からパラメーターの定義をすでに取得している場合は、そのまま dryRun に進めます。
トリガー
- async UniTask コードの記述またはレビュー
- PlayerLoopTiming の選択
- CancellationToken の処理
- WhenAll/WhenAny の組み合わせ
- async UniTask コードの記述またはレビュー、PlayerLoopTiming の選択、CancellationToken の処理、WhenAll/WhenAny の組み合わせ
UniTask - 設計ルール
参考用モジュールです。各ルールは、以下の Cysharp UniTask ソースをもとにまとめています。
- 2.5.10 —
[email protected](Unity 2018.4 をベースラインとし、2022.3/Unity 6 で積極的に使用されています)
各ルールには具体的なファイルと行を記載しているため、根拠を検証でき、AI が古い記憶に基づいて独自の判断をすることを防げます。
モード:ドキュメントのみ — 制限対象となる REST スキルはありません。どの動作モード(Approval/Auto/Bypass)でも自由に読み込めます。
このモジュールを読み込むタイミング
以下のいずれかを記述またはレビューする前に読み込んでください。
async UniTask/async UniTask<T>/async UniTaskVoidのメソッドシグネチャ.Forget()、.AttachExternalCancellation(token)、.SuppressCancellationThrow()のチェーンUniTask.Yield、UniTask.NextFrame、UniTask.Delay、UniTask.WaitForEndOfFrame、UniTask.WaitForFixedUpdateUniTask.WaitUntil、UniTask.WaitWhile、UniTask.WaitUntilValueChanged、UniTask.WaitUntilCanceledUniTask.WhenAll、UniTask.WhenAny、UniTask.WhenEachUniTask.SwitchToMainThread、UniTask.SwitchToThreadPool、UniTask.RunAsyncOperation.ToUniTask()、UnityWebRequest.SendWebRequest().ToUniTask()、Coroutine.ToUniTask()this.GetCancellationTokenOnDestroy()、GetAsyncStartTrigger()およびその他のAsyncTrigger*拡張機能- 手動完了ソースである
UniTaskCompletionSource/UniTaskCompletionSource<T> IUniTaskAsyncEnumerable<T>/UniTaskAsyncEnumerable/AsyncReactiveProperty<T>/Channel<T>Task.Run/SwitchToThreadPoolが禁止されている WebGL 固有の非同期コードパス
重要なルールのまとめ
| # | ルール | 出典アンカー |
|---|---|---|
| 1 | UniTask は readonly partial struct(値型)です。一度 await すると、その IUniTaskSource は再利用されるため、同じ UniTask 変数を2回 await すると例外が発生します。複数回 await できるメモ化されたコピーを取得するには、.Preserve() を使用してください。 | UniTask.cs:34, UniTask.cs:103-113 |
| 2 | メソッドが返す UniTask は、必ず await するか、.Forget() を呼び出すか、.AttachExternalCancellation(token) を呼び出す必要があります。放置された UniTask は、例外を UniTaskScheduler.UnobservedTaskException に通知せずに取り込みます。 | UniTaskScheduler.cs:13, UniTaskVoid.cs:11-17 |
| 3 | PlayerLoopTiming は 16 個のタイミングスロットを定義します(2020.2以降。古い Unity では 14 個)。既定の UniTask.Yield()/UniTask.Delay は PlayerLoopTiming.Update を使用します。LastPostLateUpdate と従来の WaitForEndOfFrame コルーチンを組み合わせると、観測されるフレームの順序が変わります。 | PlayerLoopHelper.cs:71-99 |
| 4 | UniTask.Delay(int ms, DelayType, PlayerLoopTiming, CancellationToken, bool cancelImmediately) は、DelayType.DeltaTime / UnscaledDeltaTime / Realtime を受け付けます。古い bool ignoreTimeScale オーバーロードも引き続き存在しますが、異なるセマンティクスが混在するため、新しいコードでは DelayType オーバーロードを優先してください。 | UniTask.Delay.cs:12-20, UniTask.Delay.cs:147-165 |
| 5 | this.GetCancellationTokenOnDestroy() は、AsyncTriggerExtensions で MonoBehaviour、GameObject、Component 向けに定義されています。通常の C# クラスにはこの拡張機能は適用されないため、明示的に CancellationTokenSource を所有する必要があります。 | Triggers/AsyncTriggerExtensions.cs:14,22,28 |
| 6 | UniTask.WhenAll(params UniTask[] tasks) と IEnumerable<UniTask> オーバーロードの両方が存在します。セマンティクスは Task.WhenAll と一致しますが、UniTask ネイティブなタスクを使用する場合は割り当てがゼロです。UniTask<T> の WhenAny は (winnerIndex, result) タプルを返します。 | UniTask.WhenAll.cs:12,22,31,41, UniTask.WhenAny.cs |
| 7 | AsyncOperation.ToUniTask(IProgress<float>, PlayerLoopTiming, CancellationToken) が標準的なアダプターです。await operation も機能しますが、operation.completed += … も設定すると、進捗コールバックが通知されないまま残ります。 | UnityAsyncExtensions.cs |
| 8 | UniTaskCompletionSource と UniTaskCompletionSource<T> は、TrySetResult/TrySetException/TrySetCanceled をサポートします。3つのうちいずれかが成功した後の呼び出しは false を返し、例外は発生しません。 | UniTaskCompletionSource.cs:573,610,754,792 |
| 9 | UniTask.SwitchToThreadPool() と UniTask.Run(...) はすべてのプラットフォームでコンパイル時に利用できますが、WebGL では実行時に NotSupportedException が発生します。`#if !UNITY_WEBGL | |
| 10 | async UniTaskVoid を返す方法は、メソッド内で await を使用できる fire-and-forget の慣用的な方法です。async void メソッドは UniTask を返せません。これは Task から移植する際によくあるコンパイルエラーです。 | UniTaskVoid.cs:11-17, UniTask.Factory.cs:112-131 |
サブドキュメントの案内
| サブドキュメント | 読むタイミング |
|---|---|
| BASICS.md | UniTask と Task の違い、構造体のセマンティクス、UniTaskVoid、ゼロアロケーションのステートマシン、AsyncUniTaskMethodBuilder |
| PLAYERLOOP.md | 16 個の値を含む PlayerLoopTiming の表、Yield/NextFrame/Delay/WaitForEndOfFrame/WaitForFixedUpdate、DelayType、従来のコルーチンとのフレーム順序 |
| CANCELLATION.md | CancellationToken のパターン、GetCancellationTokenOnDestroy(3 つのオーバーロード)、AttachExternalCancellation、CancelAfterSlim、AddTo、OperationCanceledException のフロー |
| COMPOSITION.md | WhenAll、WhenAny、WhenEach、Forget、SuppressCancellationThrow、ContinueWith、タイムアウトのパターン |
| CONVERSION.md | AsyncOperation.ToUniTask、UnityWebRequest.SendWebRequest().ToUniTask、IEnumerator.ToUniTask、Task.AsUniTask、UniTask.AsTask、UniTask.ToCoroutine |
| ASYNCENUMERABLE.md | IUniTaskAsyncEnumerable<T>、UniTaskAsyncEnumerable、AsyncReactiveProperty<T>、Channel<T>、EveryValueChanged、Publish、LINQ の非同期演算子 |
| TRIGGERS.md | AsyncTriggerBase、GetAsyncStartTrigger、GetAsyncDestroyTrigger、OnCollisionEnterAsync、OnClickAsync、MonoBehaviourMessagesTriggers、ライフサイクルに伴うキャンセル |
| PITFALLS.md | 具体的なハルシネーション/実行時の落とし穴 30 件(二重の await、Forget の呼び忘れ、WebGL のスレッドプール、トラッカーのメモリ使用量、誤った PlayerLoopTiming、コルーチン連携の不具合) |
他のモジュールへの案内
- アーキテクチャレイヤーでの
UniTask、生のTask、IEnumeratorの選択 → async を読み込みます - DOTween のトゥイーン → UniTask アダプター(
tween.ToUniTask(TweenCancelBehaviour, token))→ dotween-design を読み込みます - YooAsset のハンドル →
handle.ToUniTask()拡張機能による UniTask への変換 → yooasset-design を読み込みます - Addressables の
AsyncOperationHandle.ToUniTask()のルール → addressables-design を読み込みます - UniTask を多用するコードパスのパフォーマンスレビュー(トラッカーのコスト、ステートマシンの割り当て)→ performance を読み込みます
- UniTask を利用するコードの Asmdef 構成(
Cysharp.Threading.Tasks.asmdefの参照)→ asmdef を読み込みます
対象バージョン
UniTask 2.5.10 が対象です。それ以前の 2.x バージョンはおおむねソース互換性があります。主な違いは次のとおりです。
WaitForEndOfFrame(MonoBehaviour coroutineRunner)オーバーロードは、最近の 2.x で追加されました。2023.1 以降では、引数なしのオーバーロードが利用できます(#if UNITY_2023_1_OR_NEWER)。UniTask.Delay.cs:78-103を参照してください。UniTask.WhenEachは比較的新しい機能です。すべての 2.x ビルドに含まれているわけではありません。
迷った場合は、記憶ではなく、引用されているソースを確認してください。
コメント
Markdown 対応