3 minute read

개요


UniTask는 유니티에서 비동기 프로그래밍을 간소화하고 성능을 향상시키기 위해 만들어진 라이브러리입니다. C#의 asyncawait키워드를 기반으로 작동하며, 유니티의 코루틴보다 훨씬 적은 오버헤드로 비동기 작업을 처리할 수 있도록 설계되었습니다. 마치 택배 관리 시스템에서 여러 택배의 정보를 효율적으로 관리하고 추적하는 것과 같습니다.

UniTask는 실제 현장에서 가장 많이 쓰이는것중 하나이기 때문에 반드시 익혀두시는게 좋습니다.

특징


  • 가벼운 오버헤드: 유니티의 코루틴보다 훨씬 적은 오버헤드로 비동기 작업을 처리하여 성능 향상에 도움을 줍니다. 마치 택배 관리 시스템이 불필요한 절차를 최소화하여 운영 비용을 줄이는 것과 같습니다.

  • async와 await 지원: C#의 async와 await 키워드를 사용하여 비동기 코드를 동기 코드처럼 쉽게 작성할 수 있습니다. 마치 택배 관리 시스템에서 직관적인 인터페이스를 제공하여 누구나 쉽게 사용할 수 있는 것과 같습니다.

  • 다양한 유니티 API 통합: 유니티의 다양한 API (예: WaitForSeconds, WWW, AssetBundle 로딩 등)를 UniTask로 쉽게 변환할 수 있습니다. 마치 택배 관리 시스템이 다양한 택배 회사와 연동되어 정보를 통합 관리하는 것과 같습니다.

  • 취소(Cancellation) 지원: 비동기 작업을 취소할 수 있는 기능을 제공하여 리소스 낭비를 방지합니다. 마치 택배 배송을 중간에 취소할 수 있는 것과 같습니다.

  • 값 반환: 비동기 작업의 결과를 쉽게 반환받을 수 있습니다. 마치 택배 배송 완료 후 수령 확인을 받는 것과 같습니다.

  • 예외 처리: 비동기 작업에서 발생한 예외를 쉽게 처리할 수 있습니다. 마치 택배 배송 중 발생한 문제(예: 파손, 분실)에 대한 처리 절차를 갖추고 있는 것과 같습니다.


코루틴과의 비교


코루틴의 경우 IEnumerator객체를 생성하고 이 객체는 Heap메모리에 할당됩니다. 즉, 가비지컬렉터(GC)의 부하가 커집니다. 뿐만 아니라 코루틴이 일시중지 될 때마다 현재 상태를 저장하기 위한 추가적인 메모리 오버헤드가 발생할 수 있습니다.

반면, UniTask의 경우 기본적으로 Struct 기반으로 구현되기 때문에 Heap이 아닌Stack메모리에 할당되어 GC의 부하가 적습니다. 이로 인해 Zero Allocation효과를 받을 수 있습니다.

Zero Allocation이란?

메모리 할당을 최소화하거나 완전히 없애는 프로그래밍 기법
가비지 컬렉션(GC)의 부하를 줄여 성능을 향상시키는 것이 목적


용도에 맞게 사용하는것이 중요!

  • 간단한 작업, 빈도가 낮은 경우: 간단한 시간 지연이나 한 번만 실행되는 비동기 작업에는 코루틴을 사용해도 충분합니다. 마치 가끔씩 편지를 보내는 경우 일반 우편을 이용하는 것과 같습니다.
  • 빈번한 작업, 높은 성능 요구, 많은 수의 동시 작업, 정밀한 제어가 필요한 경우: UniTask를 사용하는 것이 좋습니다. 특히, 게임 로직, 네트워크 통신, UI 업데이트 등 성능이 중요한 부분에서 효과적입니다. 마치 중요한 서류나 긴급한 물건을 보낼 때 특송을 이용하는 것과 같습니다.

장단점


장점

  • 비동기 코드를 간결하고 가독성 높게 작성할 수 있습니다. 마치 깔끔하게 정리된 택배 관리 시스템의 정보와 같습니다.
  • 유니티 코루틴보다 성능이 우수합니다. 마치 더 빠르고 효율적인 택배 배송 시스템과 같습니다.
  • 취소 기능을 통해 리소스를 효율적으로 관리할 수 있습니다. 마치 불필요한 배송을 취소하여 비용을 절감하는 것과 같습니다.

단점

  • async와 await에 대한 이해가 필요합니다. 마치 택배 관리 시스템의 사용법을 익혀야 하는 것과 같습니다.
  • UniTask에 특화된 몇 가지 규칙들을 익혀야 합니다. 마치 택배 관리 시스템의 특별한 용어와 절차를 익혀야 하는 것과 같습니다.


주의점


  • 네임스페이스 추가: UniTask 함수를 사용하기 전에 using Cysharp.Threading.Tasks;네임스페이스를 추가해야 합니다.
  • async 메서드의 반환 타입: async메서드는 Task 또는 UniTask를 반환해야 합니다. 유니티에서는 성능상의 이점 때문에 UniTask를 사용하는 것이 권장됩니다. 마치 택배 관리 시스템에서 택배 정보를 특정 형식으로 관리하는 것과 같습니다.
  • await 사용: 비동기 작업의 결과를 기다릴 때는 await키워드를 사용해야 합니다. 마치 택배 배송 완료를 기다리는 것과 같습니다.
  • 취소 토큰 사용: 비동기 작업을 취소해야 하는 경우, CancellationToken을 사용하여 취소 요청을 전달해야 합니다. 마치 택배 배송 취소 요청서를 제출하는 것과 같습니다.

사용법


  1. UniTask 설치: 유니티 에셋 스토어 또는 Package Manager를 통해 UniTask를 설치합니다.
  2. 네임스페이스 추가: 스크립트 상단에 using Cysharp.Threading.Tasks;를 추가합니다.
  3. 비동기 메서드 작성: async 키워드를 사용하여 비동기 메서드를 작성하고, 비동기 작업 결과를 기다릴 때는 await키워드를 사용합니다. 마치 택배 정보를 입력하고 배송 상황을 확인하는 것과 같습니다.


[WaitForSeconds를 UniTask로 변환]

// 코루틴 방식
IEnumerator MyCoroutine() {
    yield return new WaitForSeconds(1f);
    Debug.Log("1 second elapsed (Coroutine)");
}

// UniTask 방식
async UniTask MyAsyncMethod() {
    await UniTask.Delay(TimeSpan.FromSeconds(1f));
    Debug.Log("1 second elapsed (UniTask)");
}

// 사용 예시
void Start() {
    StartCoroutine(MyCoroutine());
    MyAsyncMethod().Forget(); // UniTask는 Forget()으로 실행해야 함
}


[WWW 요청을 UniTask로 변환]

async UniTask DownloadText() {
    using (var www = new UnityWebRequest("https://www.example.com")) {
        www.downloadHandler = new DownloadHandlerBuffer();
        await www.SendWebRequest().ToUniTask();

        if (www.result == UnityWebRequest.Result.Success) {
            Debug.Log(www.downloadHandler.text);
        } else {
            Debug.LogError(www.error);
        }
    }
}


[CancellationToken 사용]

private CancellationTokenSource cts;

async UniTask MyCancellableMethod() {
    cts = new CancellationTokenSource();
    try {
        await UniTask.Delay(TimeSpan.FromSeconds(5f), cancellationToken: cts.Token);
        Debug.Log("Task completed.");
    } catch (OperationCanceledException) {
        Debug.Log("Task cancelled.");
    }
}

void Start() {
    MyCancellableMethod().Forget();
}

void Update() {
    if (Input.GetKeyDown(KeyCode.Space)) {
        cts.Cancel(); // 스페이스 키를 누르면 작업 취소
    }
}



Top