Receber por email
← Voltar para o catálogo

unitask

UniTask async/await for Unity — zero-alloc async, cancellation tokens, PlayerLoop integration, async LINQ. Use instead of coroutines for cancellation support and cleaner async code.

21estrelas
Atualizado há 6 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add XeldarAlz/everything-claude-unity

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/unitask/svg)](https://www.skillteca.com.br/skills/unitask)
#ai

Skills relacionadas

Ver todas de Marketing →

Alerta por categoria

Receba novas skills de Marketing toda segunda

1 email curto, só com as skills novas de Marketing. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

UniTask — Zero-Allocation Async/Await for Unity

UniTask (Cysharp) provides async/await that integrates natively with Unity's PlayerLoop, produces zero GC allocations, and supports proper cancellation. Prefer UniTask over coroutines and System.Threading.Tasks.Task in all Unity projects.

UniTask vs Coroutines vs System.Threading.Tasks.Task

| Feature | Coroutine | Task | UniTask | |---------|-----------|------|---------| | GC allocation | Enumerator + box | Task object + state machine | Zero (struct-based) | | Cancellation | Manual flag | CancellationToken | CancellationToken | | Return values | No | Yes | Yes | | Exception handling | Swallowed silently | try/catch | try/catch | | Runs on thread pool | No | Yes (dangerous in Unity) | No (PlayerLoop) | | Awaitable | No | Yes | Yes |

Basic Usage

Method Signatures

using Cysharp.Threading.Tasks;

// Awaitable, returns nothing
public async UniTask LoadLevelAsync(CancellationToken ct)
{
    await UniTask.Delay(1000, cancellationToken: ct);
}

// Awaitable, returns a value
public async UniTask<int> CalculateScoreAsync(CancellationToken ct)
{
    await UniTask.Yield(ct);
    return 100;
}

// Fire-and-forget (use sparingly, only at call boundaries)
public async UniTaskVoid OnButtonClickedAsync()
{
    await DoSomethingAsync(this.GetCancellationTokenOnDestroy());
}

CRITICAL: Never Use async void

// BAD — exceptions silently swallowed, no cancellation, GC allocation
public async void DoSomething() { ... }

// GOOD — proper error propagation, zero alloc
public async UniTask DoSomethingAsync(CancellationToken ct) { ... }

// GOOD — fire-and-forget with error logging
public async UniTaskVoid DoSomethingFireAndForget() { ... }

Waiting and Delays

// Time-based delays
await UniTask.Delay(1000, cancellationToken: ct);                    // Milliseconds
await UniTask.Delay(TimeSpan.FromSeconds(1.5f), cancellationToken: ct);

// Frame-based waits
await UniTask.Yield();                                                // Next frame
await UniTask.Yield(PlayerLoopTiming.FixedUpdate);                   // Next FixedUpdate
await UniTask.NextFrame(ct);                                          // Explicit next frame
await UniTask.DelayFrame(5, cancellationToken: ct);                  // Wait N frames

// Condition waits
await UniTask.WaitUntil(() => _isReady, cancellationToken: ct);
await UniTask.WaitWhile(() => _isLoading, cancellationToken: ct);
await UniTask.WaitUntilValueChanged(transform, t => t.position, cancellationToken: ct);

// Unity async operation wrappers
await SceneManager.LoadSceneAsync("GameScene").ToUniTask(cancellationToken: ct);
await Resources.LoadAsync<Texture2D>("myTexture").ToUniTask(cancellationToken: ct);
await UnityWebRequest.Get(url).SendWebRequest().ToUniTask(cancellationToken: ct);

Cancellation Tokens

CRITICAL: Always Pass Cancellation Tokens

Async operations that outlive their owning object cause MissingReferenceException and undefined behavior. Every async method must accept and respect a CancellationToken.

Pattern 1: GetCancellationTokenOnDestroy (Simple)

public class SimpleAsync : MonoBehaviour
{
    private async UniTaskVoid Start()
    {
        // Token auto-cancels when this MonoBehaviour is destroyed
        CancellationToken ct = this.GetCancellationTokenOnDestroy();

        await UniTask.Delay(2000, cancellationToken: ct);
        Debug.Log("This won't run if object was destroyed");
    }
}

Pattern 2: Manual CancellationTokenSource (Enable/Disable)

public class ManagedAsync : MonoBehaviour
{
    private CancellationTokenSource _cts;

    private void OnEnable()
    {
        _cts = new CancellationTokenSource();
        RunLoopAsync(_cts.Token).Forget();
    }

    private void OnDisable()
    {
        _cts?.Cancel();
        _cts?.Dispose();
        _cts = null;
    }

    private async UniTask RunLoopAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            await UniTask.Delay(1000, cancellationToken: ct);
            DoPeriodicWork();
        }
    }
}

Pattern 3: Linked Tokens (Combine Destroy + Manual Cancel)

public class LinkedTokenExample : MonoBehaviour
{
    private CancellationTokenSource _actionCts;

    public async UniTask PerformActionAsync()
    {
        // Cancel previous action if still running
        _actionCts?.Cancel();
        _actionCts?.Dispose();
        _actionCts = new CancellationTokenSource();

        // Link with destroy token so it cancels on either condition
        CancellationToken destroyCt = this.GetCancellationTokenOnDestroy();
        CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(
            _actionCts.Token, destroyCt);

        try
        {
            await DoWorkAsync(linked.Token);
        }
        catch (OperationCanceledException)
        {
            // Expected on cancellation — do nothing
        }
        finally
        {
            linked.Dispose();
        }
    }
}

Handling OperationCanceledException

public async UniTask LoadDataAsync(CancellationToken ct)
{
    try
    {
        await SomeAsyncOperation(ct);
    }
    catch (OperationCanceledException)
    {
        // Normal cancellation — cleanup silently
        return;
    }
    catch (Exception ex)
    {
        // Actual error — log and handle
        Debug.LogException(ex);
    }
}

PlayerLoop Integration

UniTask hooks into Unity's PlayerLoop for precise timing control.

// Available timing points
await UniTask.Yield(PlayerLoopTiming.Initialization);
await UniTask.Yield(PlayerLoopTiming.EarlyUpdate);
await UniTask.Yield(PlayerLoopTiming.FixedUpdate);
await UniTask.Yield(PlayerLoopTiming.PreUpdate);
await UniTask.Yield(PlayerLoopTiming.Update);
await UniTask.Yield(PlayerLoopTiming.PreLateUpdate);
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate);

// Wait for specific timing in FixedUpdate
await UniTask.WaitForFixedUpdate(ct);

// Wait for end of frame (replacement for WaitForEndOfFrame coroutine)
await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, ct);

WhenAll / WhenAny — Parallel Execution

// Wait for all tasks to complete (parallel)
(int score, string name) = await UniTask.WhenAll(
    LoadScoreAsync(ct),
    LoadNameAsync(ct)
);

// Wait for first task to complete
int winnerIndex = await UniTask.WhenAny(
    WaitForInputAsync(ct),
    WaitForTimeoutAsync(5f, ct)
);

// Typed WhenAny with result
(bool hasResult, int result) = await UniTask.WhenAny(
    FetchFromCacheAsync(ct),
    FetchFromNetworkAsync(ct)
);

// Load multiple assets in parallel
var textures = await UniTask.WhenAll(
    paths.Select(p => LoadTextureAsync(p, ct))
);

Forget and Fire-and-Forget

// Fire and forget — logs exceptions to Debug.LogException
DoSomethingAsync(ct).Forget();

// Suppress specific cancellation exceptions
DoSomethingAsync(ct).SuppressCancellationThrow().Forget();

UniTaskCompletionSource — Manual Completion

For wrapping callback-based APIs or creating custom awaitable operations.

public class DialogSystem : MonoBehaviour
{
    private UniTaskCompletionSource<DialogResult> _dialogTcs;

    public async UniTask<DialogResult> ShowDialogAsync(string message, CancellationToken ct)
    {
        _dialogTcs = new UniTaskCompletionSource<DialogResult>();

        // Register cancellation
        ct.Register(() => _dialogTcs.TrySetCanceled());

        ShowDialogUI(message);
        return await _dialogTcs.Task;
    }

    // Called by UI buttons
    public void OnConfirmClicked() => _dialogTcs.TrySetResult(DialogResult.Confirm);
    public void OnCancelClicked() => _dialogTcs.TrySetResult(DialogResult.Cancel);
}

Async LINQ

UniTask provides async LINQ operators for event streams.

using Cysharp.Threa
Compartilhar X LinkedIn