UniTask [유니테스크] 사용하기

양규빈·2024년 4월 21일
0

유니티

목록 보기
27/34
post-thumbnail

유니테스크란?

유니테스크란 유니티 엔진에서, async-await 작업을 처리하기 위한 라이브러리 중 하나입니다.

유니티는 C#을 스크립트 언어로써 사용합니다.
C#에서 기본적으로 제공하는 비동기 작업 메서드, Task가 존재함에도 불구하고 유니테스크를 사용하는 이유는 유니테스크가 싱글 스레드를 사용하는 유니티 환경에서의 Task가 가지는 단점을 보완하여 강력한 비동기 작업을 구현할 수 있도록 제작한 라이브러리이기 때문입니다.

비동기 작업을 수행한다는 측면에서 코루틴과 유사한 부분이 있지만,
유니테스크는 코루틴과 비교하여 여러가지 차이점이 있습니다.

유니테스크 설치

Window - PackageManager에 들어가, + 버튼을 클릭, Add packacge from git URL 을 선택합니다.

이후, 아래 주소를 입력하면, 유니티 테스크가 import 됩니다.

https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask

이렇게 import된 유니테스크는 상단의 위치에 생기게 됩니다.

코루틴과 유니테스크

코루틴의 단점

  1. 코루틴 함수 종료 후, IEnumrator Function에서 값을 리턴할 수 없다.
  2. StartCoroutine을 사용할 때마다 가비지 컬랙션에 할애되는 메모리 소모량이 크다.

유니테스크의 장점

  1. UniTask<T>와 같은 형태로 함수를 선언하여, 값을 Return할 수 있다.
  2. 구조체를 기반으로 제작되었기 때문에, 메모리 할당이 최소화되어, 최적화에 유리하다.
  3. 코루틴과 유사한 기능을 제공한다.
  4. 메모리 누수를 방지하기 위한 track 시스템을 제공한다.
  5. UniTask는 다양한 확장기능을 제공하여, 비동기 작업을 더 유연하게 처리할 수 있다. 예를 들어, UniRx와 통합하여 기능 추가가 가능하다.
  6. 유니테스크는 오류처리와 예외처리를 간편하게 수행할 수 있도록 지원한다. Task와 유사한 방식으로 예외 처리가 가능하며, 콜백을 통해 오류 처리도 가능하다.
  7. 유니티 엔진 뿐만 아니라 닷넷프레임워크에서도 지원이 가능하다.

유니테스크 사용하기

유니테스크의 사용은, 코루틴과 비교하여 코드를 작성해보도록 하겠습니다.

유니테스크를 사용하기에 앞서,
using Cysharp.Threading.Tasks;
라이브러리를 스크립트에 추가하여, 클래스가 사용할 수 있도록 해주어야 합니다.

n초 동안 대기하기

코루틴의 WaitForSeconds. 혹은 WaitForSecondsRealtime에 대응하는
유니테스크의 함수는 UniTask.Delay() 입니다.

System 라이브러리에 존재하는, TimeSpan을 이용하여, time값을 value로 넘기는 것이 가능합니다.

여기서 UniTaskVoid는,
UniTask상에서 구현된 void함수로 받아들이면 되겠습니다.
즉, 리턴값이 따로 존재하지 않는 설정입니다.

유니테스크 함수를 호출할 때 사용된 Forget() 메서드는 UniTask가 던지는 예외를 무시하고자 할 때, 붙는 메서드입니다.
보통 UniTaskVoid의 반환 형식을 갖는 함수를 호출할 때 사용하는데,

UniTaskVoid 반환 형식의 함수를 사용할 때 주의점이 있습니다.
await를 붙여서 함수를 호출할 수 없다는 것입니다.

이는 UniTaskVoid가 awaitable 속성이 아니기 때문입니다.

조건 만족 후 비동기 작업

상단의 코드는 curTime값이 3이 되었을 때, 비동기적으로 조건 만족을 체크하고 박스 생성 작업을 수행하는 코드입니다.

코루틴의 WaitUntill과 같은 기능을 하는
유니테스크의 WaitUntill 메서드를 이용하여 구현했습니다.

작동중인 비동기 작업 취소

비동기 작업 중인 코루틴이나 유니테스크를 취소하기 위해서는,
각각. 인스턴스화된 코루틴과 캔슬레이션 토큰 소스가 필요합니다.

즉, 작업 취소의 환경이 갖춰졌을 때.
비동기 작업이 저장된 메모리 주소에 접근할 수 있는 변수가 필요한 것입니다.

이러한 Task들은 토큰 소스를 통해서
GetCanclelationTokenOnDestroy()를 이용하여, 자동 파괴를 걸어두거나, 개발자가 직접 디포즈할 수 있습니다.

실행중인 작업 추적

유니테스크는 UniTask Tracker 창을 사용하여, 현재 활성화 되어 있는 유니테스크 작업들을 추적할 수 있습니다.

코루틴에는 존재하지 않는 기능으로,
트래커 창을 사용하여, 효율적인 메모리 관리를 할 수 있습니다.

상단에 작성된 스크립트를 씬에서 오브젝트화 하였을 때.
트래커 창에서 출력되는 작업을,

아래 사진을 통해서 체크할 수 있습니다.

코루틴과 유니티의 메서드 문법 비교

  • yield return new WaitForSeconds / yield return new WaitForSecondsRealtime
    == await UniTask.Delay
  • yield return null == await UniTask.Yield / await UniTask.NextFrame
  • yield return WaitForEndOfFrame == await UniTask.WaitForEndOfFrame
  • yield return new WaitForFixedUpdate // await UniTask.WaitForFixedUpdate
  • yield return WaitUntil == await UniTask.WaitUntil

유니테스크와 서드파티

유니테스크는 서드파티 라이브러리와 확장이 가능합니다.

유니테스크 깃허브

TextMeshPro: UniTask는 TextMeshPro의 일부 기능을 지원합니다. 이를 통해 TextMeshPro의 텍스트 및 입력 필드 이벤트를 awaitable하게 사용할 수 있습니다.

DOTween: UniTask는 DOTween을 지원하여 Tween을 awaitable하게 만듭니다. 이를 통해 DOTween의 트윈을 비동기적으로 실행하고 대기할 수 있습니다.

Addressables: UniTask는 Addressables를 지원하여 AsyncOperationHandle 및 AsyncOperationHandle<T>를 awaitable하게 만듭니다. 이를 통해 Addressables를 사용하여 리소스를 비동기적으로 로드하고 처리할 수 있습니다.

이러한 라이브러리들은 각각의 asmdef 파일에 정의되어 있으며, 해당 라이브러리를 사용할 때마다 UniTask에서 적절한 확장 기능을 자동으로 활성화합니다.

DOTween의 경우, 단순히 DOTween 패키지를 가져온 후 UNITASK_DOTWEEN_SUPPORT 스크립트 정의 기호를 정의하여 UniTask에서 DOTween을 활성화할 수 있습니다.

프로젝트에 사용

UI에 스크립트를 출력하고, next 버튼을 눌러서 장을 넘기는 코드입니다.
(코드에 대한 상세한 내용은 배틀레드-퀘스트 시스템 문서에 정리해 두었습니다.)

기존의 코드는 코루틴을 이용하여 작성되었습니다.
그리고 기존의 코루틴 함수를 이용한 구현법에서 유니테스크를 이용한 구현법으로 수정해보았습니다.

코루틴을 사용한 기존 코드

유니테스크를 사용하여 수정한 코드

profile
훌륭한 개발자를 꿈꾸는 중입니다

0개의 댓글