While Unity is synchronous, it allows the use of async functions. Asynchronous functions in Unity allow us to process logic without blocking the main thread. This means that we can execute tasks in the background without blocking up the main thread. This allows us to process tasks like loading and handling network connections while simultaneously being able to take game input or render objects. We can also use a coroutine for this functionality; however, using async functions has its benefits and use cases. Let’s look at how async functions work.
Async functions are a C# scripting feature in Unity that allows you to execute a part of the program asynchronously. They allow us to suspend a task mid-way by allowing us to wait for another task to complete first. They are used alongside the await
command and a Task
type function to ensure the task runs asynchronously. The following slides show how the processing pipeline looks like normally and with an asynchronous function:
Let us discuss the slides in a bit more detail:
Without async function: This is a regular Unity processing pipeline that is synchronous. It processes each process frame by frame, and every instruction is executed line by line in code.
With async function: Using an async function, we can start a separate processing thread to execute the commands of the awaited task we have written in the script. Before the asynchronous function, however, everything would be processed synchronously, and the main thread would continue with its frame-by-frame execution.
Note: The asynchronous function would only shift to a separate thread if an awaited task exists. If there is no awaited task, then nothing will happen.
Let us look at a script example as well.
The following code shows us an example of async functions working alongside synchronous functions:
using System.Threading.Tasks;class AsyncClass{//Main functionstatic void Main(){AsyncFunction();SynchronousFunction();}//Asynchronous function running in the backgroundstatic async Task AsyncFunction(){//Lambda expression for awaited task which runs asynchronouslyawait Task.Run(()=>{for (int i = 0; i < 10; i++){System.Console.WriteLine("Async Count called");Task.Delay(1000).Wait();}});}//Synchronous function working simultaneously with the async functionstatic void SynchronousFunction(){for (int i = 0; i < 10; i++){System.Console.WriteLine("Normal Count called");Task.Delay(1000).Wait();}}}
Let’s look at the code given above in a bit of detail:
Lines 6–10: This is our main function. We call the asynchronous function and the synchronous function in our main. The synchronous function will be called before the complete execution of our asynchronous function.
Lines 15–20: We have written a lambda expression for the awaited task in our async function. In this lambda expression, we run a loop 10 times, and between each loop, we set a delay of 1 second. During this delay, the function processes the synchronous function.
Lines 24–31: This is a simple function in which we run a loop 10 times and set a delay of 1 second between each loop.
Note: We get a warning that our synchronous function gets called before the completion of our async function but that is our intended use in this particular example.
Asynchronous functions are very useful when it comes to game development in Unity. They help us perform sequential tasks asynchronously, which prevents the blocking of our main thread. We can also perform many tasks on separate threads, like network connection and asset loading, which can greatly improve our game’s experience.
Free Resources