Tasks
An async method runs immediately until its first suspension. Use async Task<T> for a result, or async void for a legacy action with no result.
Await another script task, Motion.MoveToAsync(position, seconds), Time.Wait(seconds), or Time.NextFrame(). Native motion completes when its actual engine tween finishes; replacement, dragging, removal, or cancellation produces a canceled task.
public bool Charging;
[Repeat("replace")] public async Task<int> Charge() {
Charging = true;
try {
await Time.Wait(0.3);
return 25;
} finally {
Charging = false;
}
}Task handle
Tasks expose Id, Status, Reason, IsCompleted, IsCanceled, IsFailed, Result (non-void), and Cancel(). Result access requires completion.
Awaiting a canceled child cancels its parent; a failed child fails the parent. A parent settling cancels its unfinished children, including cross-object calls.
Every suspension requires a later active Play frame. Work created during a frame cannot consume the time preceding its creation, regardless of object order. Zero waits also yield; a startup wait may resume in the first frame. A routine resumes at most once per frame. Waits count outer gameplay seconds even when started from FixedUpdate.
Update, FixedUpdate, and End stay synchronous.
Lifetime
| Event | Owned work |
|---|---|
| Pause Play / debugger | Waits stop advancing |
| Disable component | Script continuations pause. Native systems keep their own enabled/lifetime rules |
Task.Cancel / Time.CancelAll | Cancel one task tree / this component’s tasks and unwind finally |
| Remove component/entity or replace world | Cancel before retiring the old owner |
| Stop Play | Cancel even disabled owners; enabled components run synchronous End |
| Apply changed definition | Cancel with code-replaced, release native resources, preserve compatible fields |
[Repeat("parallel")] is the compatibility default. ignore reuses an active invocation, replace cancels it before starting the next, and queue waits behind it with bounded capacity. A component scope allows 64 live tasks, including native children, with at most 32 queued tasks.
finally cannot await, start async work, or escape through return/break/continue. Cleanup has an independent 1,000-operation allowance. Native resource release is idempotent even if authored cleanup fails. Cancellation retains committed damage, loot, and other completed effects.
The debugger’s Tasks panel shows waits, parent/task identity, owned resources, source revision, and recent terminal reasons. Flow uses the same outcomes: task outcomes in Flow.
Task.All and Task.Race
Task.All(first, second) waits for all supplied tasks and returns Task<void>; result types may differ. Task.All<T>(first, second) collects matching Task<T> results into a List<T> in argument order. Task.Race(first, second) returns the first terminal outcome (completion, failure, or cancellation), not the first success. Task.Race<T> makes the type explicit.
public async Task<int> Run() {
var results = await Task.All<int>(After(.2, 4), After(.1, 7));
int winner = await Task.Race(After(.1, 2), After(10, 9));
return results[0] + results[1] + winner;
}A group takes cancellation responsibility for its inputs. Canceling the group cancels unfinished inputs, including work on another component. All fails or cancels as soon as an input does, then cancels the rest. Race preserves the first terminal outcome and cancels unfinished losers. Already-terminal race inputs are considered in argument order.
A single List<Task<T>> is accepted. Membership is snapshotted when the group is created. Duplicate handles share a subscription while retaining duplicate All result positions. Groups accept at most 64 inputs. Empty All completes successfully (a fresh empty list for All<T>); empty Race, null tasks, and ownership cycles fail explicitly. Generic All cannot produce nested lists. Every await still yields to a later frame, even when its group was already complete.
Groups cannot start inside pure functions or finally. See Task and Time.
Task is a reserved name — language.
Related
- Time groups and pausing
- Gameplay time
- Scripts and Flow
- SpriteAnimator
PlayAsync/WaitForMarker