부트캠프/Unity [ 스파르타 ]
[스파르타 ][TIL] 유니티 스파르타 7기 58일차 - UniTask
맏난거
2025. 5. 1. 21:00
🔷 1. 왜 UniTask를 쓰는가?
Unity는 기본적으로 Coroutine 기반의 비동기 처리를 제공하지만, 다음과 같은 단점이 있습니다:
Coroutine의 단점UniTask의 장점
반환값을 가질 수 없음 | UniTask<T>로 반환값을 가짐 |
예외처리가 번거로움 (try-catch 안됨) | try-catch로 자연스럽게 예외처리 가능 |
중첩 호출 시 복잡하고 유지보수 어려움 | await로 직관적인 비동기 흐름 가능 |
GC 발생 없음(좋음)이지만 타입 제약 있음 | UniTask는 GC 거의 없음 + 제네릭 지원 |
🔷 2. UniTask 기본 사용법
✅ 단순 지연
using Cysharp.Threading.Tasks;
public async UniTaskVoid DelayExample()
{
Debug.Log("Start");
await UniTask.Delay(1000); // 1초 대기
Debug.Log("End");
}
✅ 반환값 있는 경우
public async UniTask<int> GetData()
{
await UniTask.Delay(500);
return 42;
}
public async UniTaskVoid UseData()
{
int result = await GetData();
Debug.Log(result); // 42
}
🔷 3. UniTask와 Coroutine 비교
항목CoroutineUniTask
반환값 지원 | ❌ 불가능 | ✅ UniTask<T> 사용 가능 |
예외 처리 | ❌ try-catch 불가능 | ✅ try-catch 사용 가능 |
GC 발생량 | ✅ 적음 | ✅ 매우 적음 (Zero Allocation 구조체) |
Unity 생명주기 통합 | ❌ 직접 관리 필요 | ✅ OnDestroy와 연동 가능 |
🔷 4. 취소 (Cancellation)
CancellationTokenSource cts = new();
await UniTask.Delay(5000, cancellationToken: cts.Token);
// 중간에 cts.Cancel() 호출 시 취소됨
🔷 5. 사용 시 주의사항
- 메인 스레드에서만 작동하는 Unity API 사용 시 await 뒤에는 반드시 메인스레드로 돌아와야 함
→ UniTask.SwitchToMainThread() 또는 PlayerLoop 기반 호출 사용 - UniTaskVoid는 fire-and-forget용으로, 예외가 잡히지 않으므로 최소한으로만 사용
🔷 6. Unity 관련 예시
public async UniTask WaitForButton(Button btn)
{
await btn.OnClickAsync(); // UniTask가 지원하는 확장 메서드
Debug.Log("Button Clicked!");
}
✳️ UniTask는 언제 쓰면 좋을까?
- 복잡한 비동기 흐름 (Coroutine으로는 너무 꼬임)
- 반환값이나 예외 처리 필요
- 네트워크 통신, 리소스 로딩, 애니메이션 처리 등