본문으로 건너뛰기

AchTask

AchTask는 UniTask와 System.Threading.Tasks.Task를 하나의 API로 통합하는 비동기 래퍼입니다. 프로젝트에 UniTask가 설치되어 있으면 자동으로 UniTask를 사용하고, 없으면 Task로 폴백합니다.

설치 감지

com.cysharp.unitask 패키지가 프로젝트에 존재하면 ENABLE_UNITASK 심볼이 자동 정의됩니다. 별도 설정 없이 asmdef의 versionDefines가 감지하므로 코드와 문서를 바꿀 필요가 없습니다.

환경내부 구현
UniTask 설치됨UniTask / UniTask<T>
UniTask 없음System.Threading.Tasks.Task / Task<T>

await 지원

AchTask는 직접 await할 수 있습니다.

await AchTask.Delay(2f);
await AchTask.WaitUntil(() => isReady);

정적 팩토리

Delay / DelayRealtime

// 게임 시간 기준 대기 (UniTask: Time.timeScale 반영 / Task 폴백: 벽시계)
await AchTask.Delay(1.5f);

// 실제 경과 시간 기준 대기 (timeScale 무관)
await AchTask.DelayRealtime(1.5f);

// CancellationToken 지원
var cts = new CancellationTokenSource();
await AchTask.Delay(5f, cts.Token);

주의: Delay는 UniTask 환경에서 Time.timeScale을 반영합니다. 슬로우모션 중에도 실제 시간으로 대기하려면 DelayRealtime을 사용하세요.

WaitUntil

// 조건이 참이 될 때까지 대기
await AchTask.WaitUntil(() => player.IsGrounded);

// 취소 가능
await AchTask.WaitUntil(() => dialogueFinished, cts.Token);

WhenAll / WhenAny

var a = AchTask.Delay(1f);
var b = AchTask.Delay(2f);
var c = AchTask.Delay(3f);

// 셋 모두 완료될 때까지
await AchTask.WhenAll(a, b, c);

// 가장 먼저 끝나는 하나가 완료될 때까지
await AchTask.WhenAny(a, b, c);

CompletedTask

// 이미 완료된 태스크 (조건 분기 반환 등에 유용)
return condition ? DoWorkAsync() : AchTask.CompletedTask;

반환값 — AchTask<T>

public static AchTask<string> FetchNameAsync()
{
return AchTask<string>.FromResult("Player");
}

string name = await FetchNameAsync();

암묵적 변환

UniTask 또는 Task와 상호 변환할 수 있습니다.

// UniTask 환경
UniTask uniTask = someAchTask; // AchTask → UniTask
AchTask achTask = someUniTask; // UniTask → AchTask

// Task 폴백 환경
Task task = someAchTask.AsTask(); // AchTask → Task
AchTask from = someTask; // Task → AchTask (암묵적)

전체 예시

// 단순 순차 대기
async AchTask LoadSequenceAsync(CancellationToken ct)
{
await AchTask.Delay(0.5f, ct); // 페이드 인
await AchTask.WaitUntil(() => dataLoaded, ct);
await AchTask.Delay(0.2f, ct); // 전환 여유
}

// 여러 작업 병렬 실행
async AchTask InitAllAsync()
{
await AchTask.WhenAll(
LoadAudioAsync(),
LoadTableAsync(),
LoadUserDataAsync()
);
}

// 먼저 끝나는 쪽으로 분기
async AchTask RaceAsync()
{
await AchTask.WhenAny(
AchTask.Delay(3f), // 타임아웃
AchTask.WaitUntil(() => input) // 유저 입력
);
}

관련 문서