# Async Code Unity 6's **`Awaitable`** is the first-party way to write `async` / `await` in gameplay code without paying the cost of a .NET `Task` on every wait. This series compares `Awaitable` to **iterator coroutines** and to `Task`, covers the built-in wait helpers and thread switches, and treats **cancellation** as a required part of the API — especially `destroyCancellationToken` and `Application.exitCancellationToken`. **Target:** Unity **6000.5+**. The same `Awaitable` surface is in Unity 6 generally, including **Unity 6.3 LTS (6000.3.27f2+)** for VR work in this vault ([[0.Choosing a Unity Version]]). Confirm any edge-case behaviour (for example, how a given package's handle converts to an awaitable) against the Editor you are on. > [!warning] Code not compiled > Scripts were checked against the Unity 6000.5 `Awaitable` Scripting API and the "Asynchronous programming with the Awaitable class" manual on 2026-11-10. **They have not been compiled or run in Unity.** > [!note] Verification status > **Verified APIs:** `Awaitable` as an async return type; `IsCompleted`, `Cancel`, `LogExceptionsAndForget`; static `NextFrameAsync`, `EndOfFrameAsync`, `FixedUpdateAsync`, `WaitForSecondsAsync`, `FromAsyncOperation`, `MainThreadAsync`, `BackgroundThreadAsync`; continuation rule (resume on main if called from main, otherwise thread pool, except the two thread-switch helpers); `WaitForSecondsAsync` is main-thread only and completes on the main thread; pooled instances **must not be awaited twice**; `destroyCancellationToken`; `Application.exitCancellationToken`; cancellation throws `OperationCanceledException`. > **Not verified:** a first-party `Awaitable` extension on Addressables 2.9 handles (use `handle.Task`, a coroutine, or Addressables 4.x `ToAwaitable()` — [[3. Loading Instantiating and Releasing]]); exact interaction of `LogExceptionsAndForget` with custom log handlers. ## Parts | # | Note | Covers | |---|---|---| | 1 | [[1. Awaitable versus Coroutines and Task]] | When to use each model, pooling, SynchronizationContext | | 2 | [[2. Awaitable Waits and Thread Switches]] | The built-in wait helpers, `FromAsyncOperation`, background work | | 3 | [[3. Cancellation Tokens]] | `destroyCancellationToken`, `exitCancellationToken`, linked tokens | | 4 | [[4. Worked Examples - Scenes Delays and Loads]] | Scene load, a hit-react delay, wrapping an Addressables handle | | 5 | [[5. Async Pitfalls]] | Double-await, fire-and-forget, dead objects, Play Mode exit | ## Design lens (Level Up!) Timing *is* feel: hit-stop, door telegraphs, camera blends, and onboarding prompts (Levels 9-12 in [[Level Up! (Review)]]) are all "wait, then do the next thing" problems. Coroutines have done this in Unity for years. `Awaitable` gives you the same non-blocking waits with clearer errors and cancellation, so a destroyed enemy does not keep running a coroutine you forgot to stop. ## Patterns used (Game Programming Patterns) - **Command / Subclass Sandbox** - an async method is a sequence of actions; keep it readable, cancel the whole sequence. - **Object Pool** - `Awaitable` instances themselves are pooled (official warning: do not await one instance twice). - **Observer** - cancellation tokens are the cooperative "please stop" signal, not a callback soup. See [[Game Programming Patterns (Review)]]. ## Related (existing) - [[SceneManagement in Unity 6]] / [[Level Manager]] - [[Addressables]] and [[3. Loading Instantiating and Releasing]] - [[Unity Test Framework]] — async `Task` tests are supported; do not return `Awaitable` from a test method ([[3. UnityTest Async Tests and Domain Reloads]]) - [[2. CPU Allocations and Incremental GC]] — `Task` has more allocation and scheduling cost than `Awaitable` - [[Localization]] — `GetLocalizedStringAsync` and initialization operations - [[Input System]] — do not "await a button" if a proper action callback already exists - [[Cinemachine 3]] — blends are usually time-driven by the camera brain; you await *your* beat, not the brain's internals, unless you have a documented hook ## Sources - Asynchronous programming with the Awaitable class (6000.5): https://docs.unity.com/en-us/engine/6000.5/manual/scripting/optimization/async-await-support - Awaitable completion and continuation (6000.5): https://docs.unity.com/en-us/engine/6000.5/manual/scripting/optimization/async-await-support/async-awaitable-continuations - `Awaitable` Scripting API: https://docs.unity3d.com/6000.5/Documentation/ScriptReference/Awaitable.html - `Awaitable.WaitForSecondsAsync`: https://docs.unity3d.com/6000.5/Documentation/ScriptReference/Awaitable.WaitForSecondsAsync.html - `Awaitable.Cancel`: https://docs.unity3d.com/6000.5/Documentation/ScriptReference/Awaitable.Cancel.html - `MonoBehaviour.destroyCancellationToken`: https://docs.unity3d.com/6000.5/Documentation/ScriptReference/MonoBehaviour-destroyCancellationToken.html - `Application.exitCancellationToken`: https://docs.unity3d.com/ScriptReference/Application-exitCancellationToken.html