Implementing Asynchronous Object Rotation in Unity with async/await and Coroutines

The C# async/await pattern offers a structured approach to managing asynchronous operations in Unity, providing an alternative to traditional coroutines. This method can enhance control over game logic by simplifying concurrent and sequential task execution.

Extension Method for Child Collection

A helper method gathers all child Transforms from a parenet object into a list.

using UnityEngine;
using System.Collections.Generic;

public static class TransformCollectionHelper
{
    public static void FetchAllChildren(this Transform parent, List<Transform> childList)
    {
        for (int idx = 0; idx < parent.childCount; idx++)
            childList.Add(parent.GetChild(idx));
    }
}

Concurrent Rotation Using async/await

Objects rotate simultaneously. The async void method starts multiple tasks without waiting for completion.

using UnityEngine;
using System.Collections.Generic;
using System.Threading.Tasks;

public class AsyncRotationController : MonoBehaviour
{
    private List<Transform> _targetObjects = new List<Transform>();

    private void Begin()
    {
        transform.FetchAllChildren(_targetObjects);
        for (int i = 0; i < _targetObjects.Count; i++)
        {
            PerformRotationAsync(i);
        }
    }

    private async void PerformRotationAsync(int objectIndex)
    {
        float finishTime = Time.time + 1.5f;
        while (Time.time < finishTime)
        {
            _targetObjects[objectIndex].Rotate(Vector3.up * 120 * Time.deltaTime);
            await Task.Yield();
        }
    }
}

Sequential Rotation Using async/await

Objects rotate one after another. The await keyword pauses execution untill each task finishes.

private async void BeginSequential()
{
    transform.FetchAllChildren(_targetObjects);
    for (int i = 0; i < _targetObjects.Count; i++)
    {
        await ExecuteRotationTask(i);
    }
}

private async Task ExecuteRotationTask(int objectIndex)
{
    float rotationEnd = Time.time + 1.5f;
    while (Time.time < rotationEnd)
    {
        _targetObjects[objectIndex].Rotate(Vector3.up * 120 * Time.deltaTime);
        await Task.Yield();
    }
}

Concurrent Rotation Using Coroutines

Traditional coroutine implementation for simultaneous rotation.

private void BeginCoroutine()
{
    transform.FetchAllChildren(_targetObjects);
    for (int i = 0; i < _targetObjects.Count; i++)
    {
        StartCoroutine(RotateCoroutine(i));
    }
}

private IEnumerator RotateCoroutine(int objectIndex)
{
    float stopTime = Time.time + 1.5f;
    while (Time.time < stopTime)
    {
        _targetObjects[objectIndex].Rotate(Vector3.up * 120 * Time.deltaTime);
        yield return null;
    }
}

Sequential Execution with Coroutines

Coroutines require nested yield return StartCoroutine() calls for sequential flow, which can become verbose.

private IEnumerator RunSequence()
{
    yield return StartCoroutine(FirstAction());
    yield return StartCoroutine(SecondAction());
    yield return StartCoroutine(ThirdAction());
}

private IEnumerator FirstAction()
{
    yield return new WaitForSeconds(1.0f);
}
// ... Similar methods for SecondAction and ThirdAction

Coordinating Multiple Async Tasks

The Task.WhenAll method waits for a collection of tasks to complete before proceeding.

public class TaskCoordinator : MonoBehaviour
{
    private List<Transform> _targetObjects = new List<Transform>();
    private Task[] _rotationTasks;

    private async void Initialize()
    {
        transform.FetchAllChildren(_targetObjects);
        _rotationTasks = new Task[_targetObjects.Count];

        for (int i = 0; i < _targetObjects.Count; i++)
        {
            _rotationTasks[i] = ExecuteRotationTask(i);
        }

        await Task.WhenAll(_rotationTasks);
        Debug.Log("All rotation tasks completed.");
    }

    private async Task ExecuteRotationTask(int objectIndex)
    {
        float durationEnd = Time.time + 1.5f;
        while (Time.time < durationEnd)
        {
            _targetObjects[objectIndex].Rotate(Vector3.up * 120 * Time.deltaTime);
            await Task.Yield();
        }
    }
}

Tags: unity C# async-await Coroutines Asynchronous Programming

Posted on Sun, 10 May 2026 00:20:21 +0000 by novicephp