Unity Async Operations with UniTask
When it comes to game development in Unity, asynchronous programming is essential for handling tasks like loading scenes, managing UI transitions, or triggering animations without freezing gameplay. While Unity’s coroutines are a helpful tool, they can be resource-intensive and lack flexibility. This is where UniTask by Cysharp comes in. It’s an optimized, high-performance alternative to coroutines and the async/await pattern in Unity, designed specifically to reduce memory overhead and streamline async operations.
In this guide, I’ll walk you through why UniTask is a game-changer for Unity developers and show you how to implement it with practical examples.
Step 1: Installing UniTask
add UniTask to our project. Here’s how:
Once imported, UniTask will be ready for use in your project.
Step 2: Replacing Coroutines with UniTask
A typical use case in Unity is waiting for a few seconds before proceeding with an action. Here’s how to do it with a coroutine:
IEnumerator MyCoroutine()
{
yield return new WaitForSeconds(1);
Debug.Log("One second passed");
}
With UniTask, you can write this code without the coroutine syntax:
using Cysharp.Threading.Tasks;
async UniTaskVoid MyUniTaskMethod()
{
await UniTask.Delay(1000); // Delay for 1000 milliseconds (1 second)
Debug.Log("One second passed with UniTask");
}
Step 3: Utilizing Unity-Specific Awaiters
UniTask includes Unity-specific awaiters like WaitForEndOfFrame, WaitForSeconds, and WaitUntil, which means you can await Unity’s own events without writing a coroutine.
async UniTaskVoid WaitForEndOfFrameExample()
{
await UniTask.WaitForEndOfFrame();
Debug.Log("End of Frame reached");
}
Suppose you want to wait until an enemy’s health drops to zero before proceeding. You can use UniTask.WaitUntil:
int enemyHealth = 100;
async UniTaskVoid WaitForEnemyDefeat()
{
await UniTask.WaitUntil(() => enemyHealth <= 0);
Debug.Log("Enemy defeated!");
}
Step 4: Handling UI and Scene Transitions
In many games, you need to display a loading message or a “loading” animation while waiting for a scene to load or a task to complete. Here’s how you can manage UI with UniTask.
Recommended by LinkedIn
Example: Displaying a Loading Message
public Text loadingText;
async UniTaskVoid ShowLoadingMessage()
{
loadingText.text = "Loading...";
await UniTask.Delay(2000); // Display for 2 seconds
loadingText.text = "Load Complete!";
}
Example: Scene Transition
using UnityEngine.SceneManagement;
async UniTaskVoid LoadSceneAsync(string sceneName)
{
loadingText.text = "Loading...";
await SceneManager.LoadSceneAsync(sceneName).ToUniTask();
loadingText.text = "Load Complete!";
}
Step 5: Using Cancellation Tokens
Sometimes, you may need to cancel a task mid-execution. UniTask provides built-in support for CancellationToken, allowing you to cancel async operations whenever necessary.
Example: Task with Cancellation
CancellationTokenSource cts = new CancellationTokenSource();
async UniTaskVoid PerformCancelableTask()
{
try
{
await UniTask.Delay(5000, cancellationToken: cts.Token); // 5-second delay
Debug.Log("Task completed without cancellation");
}
catch (OperationCanceledException)
{
Debug.Log("Task was canceled");
}
}
// To cancel the task
cts.Cancel();
Advanced Usage: Combining Multiple UniTasks
UniTask supports methods like WhenAll and WhenAny, allowing you to combine multiple asynchronous tasks efficiently.
Example: Running Multiple Tasks in Parallel
async UniTaskVoid RunMultipleTasks()
{
var task1 = UniTask.Delay(1000); // 1-second delay
var task2 = UniTask.Delay(2000); // 2-second delay
await UniTask.WhenAll(task1, task2);
Debug.Log("Both tasks completed");
}
WhenAll waits for all tasks to complete, while WhenAny returns as soon as one task finishes. This lets you create flexible and efficient async logic.
UniTask is a powerful tool that gives Unity developers an edge in handling asynchronous code, making it possible to create responsive gameplay with minimal memory allocation. With simple setup, Unity-specific awaiters, cancellation support, and integration with popular libraries like DOTween, UniTask offers a rich feature set tailored for game development.
By switching from coroutines to UniTask, you can improve both the performance and readability of your code, helping you create smoother and more enjoyable player experiences. Give UniTask a try in your next project and see the difference it makes!
Co-owner / Unity Developer w Last Qubit
1moLoving UniTask, using it in most of our projects :D