유니티에서 사용되는 코루틴은 비동기 프로그래밍을 수행하기 위한 기능 중 하나이다.
코루틴은 일시 중지 할 수 있는 함수의 실행을 가능하게 하며,
특정 조건이 충족될 때까지 기다린 후에 실행을 계속할 수 있도록 한다.
코루틴의 기본적인 원칙은 ‘IEnumerrator’ 인터페이스를 반환하는 함수를 통해 작성된다.
⇒ 비동기 처리를 해주는 특수한 메서드. 함수 실행을 일시중지 시킬 수 있다.
유니티에서 UniTask는 비동기 작업을 처리하기 위한 도구로, 유니티에서 내장되어 있는 코루틴 기능을 대체하며 async/await 패턴을 지원한다.
일반적인 C#의 Task와 비교하여, UniTask는 유니티에서 더 효율적으로 동작하도록 설계되었다.
주로 WebGL 빌드와 같은 플랫폼에서 기본 Task의 제한을 극복하기 위해 사용되었다.
https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask
장점
단점
장점
단점
UniTask는 Zero Allocation 기능을 제공하여 메모리 할당을 최소화한다. 불필요한 가비지 컬렉션(GC)을 방지하여 프레임 드랍이나 렉을 줄일 수 있다.
코루틴은 메모리 할당을 필요로 한다. ⇒ new 명령어
private void Start()
{
UniWait().Forget();
}
// Delay 함수
async UniTaskVoid UniWait()
{
await UniTask.Delay(TimeSpan.FromSeconds(3f));
}
특정 조건이 될 때까지 기다려야 하는 조건
async UniTaskVoid UniWait()
{
await UniTask.WaitUntil(()=> count == 7);
}
private CancellationTokenSource cancel = new CancellationTokenSource();
private void Update()
{
if (~~)
{
cancel.Cancel();
}
}
async UniTaskVoid UniWait()
{
// cancle.Token 할당
await UniTask.Delay(TimeSpan.FromSeconds(3), cancellationToken: cancel.Token);
}
만약 특정 조건이 만족될 때까지 실행되는 while문의 경우 Cancellation Token이 Cancel 될 때 while 문을 종료해 주는 로직을 따로 작성해주어야 합니다.
private async UniTask WaitUntilInitializedAsync(CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested) // 종료여부
{
break;
}
/~
~/
await UniTask.Delay(100, ignoreTimeScale:true, cancellationToken: cancellationToken);
}
}
var token = this.GetCancellationTokenOnDestroy();
await UniTask.Delay(1000, cancellationToken: token);
GetCancellationTokenOnDestroy 함수는 UniTask 라이브러리의 일부로 제공되며, GameObject나 Component가 파괴될 때 발생하는 취소 토큰을 가져온다.
이 함수를 사용하면 GameObject나 Component가 파괴된 시점에 UniTask를 취소할 수 있다.
위 코드를 예시로 들면, UniTask.Delay는 1초 후에 완료되도록 예정되어 있지만, 해당 GameObject가 그전에 파괴되면 UniTask는 취소된다.
// yield return null 대체
await UniTask.Yield();
await UniTask.NextFrame();
// WaitForEndOfFrame(requires MonoBehaviour(CoroutineRunner)) 대채품
await UniTask.WaitForEndOfFrame(this)
private async UniTaskVoid UpdateUniTask()
{
while (true)
{
///
~~
///
await UniTask.Yield(PlayerLoopTiming.Update);
}
}
var (google, bing, yahoo) = await UniTask.WhenAll(task1, task2, task3);