배운거 잊지 않도록 하는 메모 겸 튜토리얼성 정보예요.


PC에 최적화 되어있고 본인도 막 배운 정보니까 틀린 점 있으면 댓글 부탁.




1. UniTask


C#에는 기본적으로 Task async/await 비동기 코드가 존재하지만 Unity의 생명주기 기반 싱글스레드 환경에서는 적합하지 않다.


이런 유니티에서 async/await를 사용 가능하게 만들어주는 라이브러리가 UniTask이다.




2. Coroutine을 써야 하는 이유 vs UniTask를 써야하는 이유



Coroutine


- 추가 라이브러리가 설치가 필요 없다.


- 사용법이 비교적 쉬운편이며 리턴값이 필요 없고 yield return 값을 캐싱할 수 있는 간단한 비동기 작업에 적합하다.


- 컴포넌트가 비활성화되면 코루틴도 자동으로 비활성화된다.



UniTask


- 클래스가 아닌 스트럭트 기반이라 캐싱하지 않아도 가비지가 발생하지 않는다.


- CancellationTokenSource와 내장된 추가 함수를 사용하여 비동기 작업을 섬세하게 컨트롤할 수 있다.


- 필수 에셋인 DoTween과의 연계가 가능하다.




3. 사용법


유니태스크는 기본적으로 UniTask, UniTask<T>, UniTaskVoid의 반환값을 가지며 실행하는 방법은 다음과 같다.


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d66f99e11cd6e8fc1fd70771f42a1b81d9bd564


UniTaskVoid는 await로 사용할 수 없지만 비용이 저렴하다는 장점이 있다.


UniTask().Forget()와 _ = UniTask();는 동일하게 작동하지만 Forget()을 사용하는 것을 권장한다. (댓글 참고)




4. CancellationTokenSource


기본적으로 유니태스크는 코루틴과 달리 컴포넌트가 비활성화 되어도 자동으로 취소되지 않는다.


그래서 CancellationTokenSource를 사용하여 UniTask의 비동기 작업을 제어해야 한다.




a15714ab041eb360be3335625683746f0153452ad6a7eb89d63263f99915cd6ebc05e5bce68f26e4ccca72b3


CancellationTokenSource 객체를 생성하여 await UniTask 메서드의 인수로 넣으면


cts.Cancel()을 하는 즉시 await UniTask 이후의 코드는 취소된다.




a15714ab041eb360be3335625683746f0153452ad6a7eb89d63261f09e16cd6e1d84ebee97bbe8368b2ac0a1dd


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63261f39d1dcd6e3c5be2f4b9aa53fe0400ff219e


만약 이후의 코드를 실행하고 싶다면 .SuppressCancellationThrow()를 붙여줘야한다.


SuppressCancellationThrow() 뒤의 코드는 실행되었지만, 없다면 실행되지 않은 모습이다.




기타 CancellationTokenSource의 특징은 다음과 같다


- Cancel() 한 CancellationTokenSource는 원상복구가 불가능하다.


- CancellationTokenSource는 클래스 기반이므로 가비지가 생성된다.


- Dispose() 함수로 메모리에서 해제하여 가비지를 수동으로 제거할 수 있다.




a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d67f5981ccd6e24ef2f0382f9e7fdaf333af1dd


위 특징들로 인해 기본적인 사용법은 사진과 같다.


CancellationTokenSource를 전역변수로 설정하여 오브젝트가 활성화 될 때 객체를 생성하고 비활성화 될 때 Cancel 및 Dispose를 하는 것이다.




5. DoTween과의 연계


유니티의 필수 에셋 DoTween과 연계도 가능하다.


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d63f19f17cd6efc22ecd9d1fc2d303462bc38b4


Project Settings > Player > Scripting Define Symbols에


UNITASK_DOTWEEN_SUPPORT 를 입력하면 된다.




a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d63f59f17cd6ec95bc6d1088eb95ea937195d


그러면 await 에 DoTween 객체를 사용가능하다.


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d63f59913cd6e4918b0abcb3140b9c9bcdc72


다만 두트윈을 그냥 사용할 때에는 경고가 뜨기 때문에 _ = 으로 결과값을 버려주어야 한다.


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d66f29d16cd6ea44e9576effad5df5d8690558c


두트윈에 .ToUniTask를 붙이면 UniTask의 특정 메소드(WhenAll, WhenAny 등)의 인수로 활용 가능하며 cancellationToken도 넣을 수 있다.





a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d61f99e16cd6eed20d7f9ff1cd0555ce011a39d


만약 두트윈과 유니태스크(또는 코루틴)를 둘 다 사용 중이라면 위쪽과 같은 코드가 만들어 질 수 있다.


하지만 두트윈이 끝나기 전에 UniTask.WaitForSeconds(10f)이 먼저 종료되어 버그가 발생할 수 있으므로


아래쪽처럼 WhenAll로 묶는 사용법을 권장한다.



a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d60f89e13cd6ed821489fe6cdd9c09384683e60


a15714ab041eb360be3335625683746f0153452ad6a7eb89d63d60f69e1ccd6e967f4b21d23fe58259321768c1


작업을 취소하는 방법은 .ToUniTask로 CancellationTokenSource를 등록하는 방법 외에도


await된 Tweener를 Kill, Complete 등을 하는 방법이 있다.


위 두 코드는 결과가 같다.