Introduction to Asynchronous Programming in Unity

Dive deeper into the world of asynchronous programming in Unity by creating a fun town-builder game. By Johnny Thompson.

5 (3) · 3 Reviews

Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Catching Exceptions

When you pressed Escape, you may have noticed that an exception showed up in the debug console. This is because whenever a task gets canceled at runtime, an exception is thrown by CancellationToken.

Async cancellation exception

In this section, you’ll learn how to catch these exceptions and implement your own custom error handling for canceled tasks. This is easy to do using CancellationToken.

In the BuildStructure method, surround the calls to BuildRoadAsync and BuildHouseAsync in a try...catch block. Here’s what the code should look like once wrapped in a try...catch block for the BuildHouseAsync Task. (Don’t forget to do the BuildRoadAsync one too):

var buildHouseTask = BuildHouseAsync(houseProperties, buildPosition, cancellationToken);

try
{
    await buildHouseTask;
    var houseCost = buildHouseTask.Result;
    uiManager.NewStructureComplete(houseCost, buildPosition);
}
catch
{
    Debug.LogWarning("Building House Cancelled");
}

The task is now awaiting inside try. If it completes successfully, the remaining code in try will run, displaying the appropriate UI effect. If Task throws an exception through CancellationToken, the code inside catch will run instead. For simplicity and the purposes of this tutorial, a warning is printed to the console. For your own project, you might want to handle this in a better way.

Go back to Unity, enter play mode, and test your exception catching. Cancel a house halfway through its building process. Rather than a system-generated error, you now see the custom warning you printed through code.

Async cancellation warning

Choosing Asynchronous Programming vs. Coroutines

Now that you’ve learned about C# asynchronous methods, you might have found similarities to coroutines in Unity. However, while they are similar, key differences between the two make each of them work better in certain situations.

Coroutines are a type of method that allows code to be executed over a stretched period of time. Often, programmers use coroutines for moving GameObjects, setting countdown timers or fading textures between colors. Basically, they suit gameplay programming quite well.

You can learn more about how to use coroutines in the official Unity documentation.

Advantages of async Over Coroutines

One of the biggest advantages of async over coroutines is its ability to return values. For example, in Wenderlich-Topia, the cost of building the house is calculated asynchronously while the house is being built. Once the house is complete, the code returns the total cost of the house’s value, and the result is available in the Task result variable. Coroutines can’t return any values.

Async methods can also run on threads that aren’t the main thread. This means they can continue working on complex tasks without impacting performance on the main thread.

While coroutines also run in the background, they run on the main thread. This means they could impact the performance of the game if they’re doing complex operations.

Finally, a major advantage of async is that many external libraries and APIs also use async. This makes it easy to integrate others’ asynchronous methods into your code.

Deciding When to Use Coroutines

Coroutines are best used for set it and forget it scenarios when you need to execute code over time but don’t need any results and don’t want to manage your code. Once the coroutine is complete, it can trigger some additional behaviors to happen. (An example of this being the one described earlier – changing the color of a GameObject over time).

Additionally, because coroutines are a Unity feature, they’ll stop when the program ends. You won’t have the same problem with asynchronous code, which would continue running even after the application stops. Unity handles this cancellation for you. As you saw before, the Unity engine does not handle the cancelation of async Tasks.

Coroutines also integrate well with other Unity features and a game’s update loop. With coroutines, you can simply call yield return break; to halt a method’s execution and return to that point in the method on the next frame. Put a yield inside a for or while loop and you can make things move or change over time.

You can achieve similar behavior with async in Unity, but of course, being a C# language feature, it wasn’t built with this use case in mind, so the code is a bit messier when trying this kind of scenario with Unity.

Where to Go From Here?

You can use the Download Materials button at the top and bottom of this tutorial to download the starter and final projects.

Now, you hopefully understand how to use asynchronous methods in Unity and know when to use them (and when not to).

To increase your skills, practice implementing what you learned in some of your own projects.

As a next step, you could graduate to integrating with other asynchronous features such as Unity’s Addressable Asset System. This asynchronous way of loading assets into your game is preferable to loading assets from the Resources folder. For more information on the Addressable Asset System, check out Introduction to Modding Unity Games with Addressables from raywenderlich.com.

You can also learn about writing multithreaded code using something like Unity’s C# Job System. Check out the raywenderlich.com tutorial Unity Job System and Burst Compiler: Getting Started on how to create a wave generator using Unity’s C# Job System.

We hope you enjoyed this tutorial. If you have any questions or comments, please feel free to join the forum discussion below!

Johnny Thompson

Contributors

Johnny Thompson

Author

Srikar Mutnuri

Tech Editor

Yuliya Goldshteyn

Editor

Julia Zinchenko

Illustrator

Sean Duffy

Final Pass Editor

Tammy Coron

Team Lead

Mauro Fuentes

Topics Master

Over 300 content creators. Join our team.