GetCancellationTokenOnDestroy()UniTask는 MonoBehaviour가 파괴되는 시점에 자동으로 CancellationToken을 취소해 주는 확장 메서드를 제공함.
public class MyLoader : MonoBehaviour
{
async UniTaskVoid Start()
{
// 이 객체가 Destroy되면 token이 Cancel되어 대기 중인 await가 즉시 해제됩니다
await LoadAndBuildAsync(this.GetCancellationTokenOnDestroy());
Debug.Log("Load 끝");
}
async UniTask LoadAndBuildAsync(CancellationToken token)
{
// 긴 로딩 시뮬레이션
await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: token);
if (token.IsCancellationRequested) return;
// ... 나머지 빌드 작업
}
}
CancellationTokenSource 관리 불필요Forget() 쓰면 예외가 로그에 남지 않으므로, 에러 핸들링이 필요할 땐 .Forget(e => Debug.LogError(e)) 같은 오버로드 활용때로는 Destroy와 무관하게 직접 취소 시점을 제어하고 싶을 때가 있음
public class MyWatcher : MonoBehaviour
{
CancellationTokenSource _cts;
void Awake()
{
_cts = new CancellationTokenSource();
WatchSomethingAsync(_cts.Token).Forget();
}
async UniTask WatchSomethingAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// 반복 검사
await UniTask.Delay(1000, cancellationToken: token);
Debug.Log("감시 중...");
}
}
void OnDestroy()
{
// ① 토큰 취소
_cts.Cancel();
// ② CTS 객체 해제
_cts.Dispose();
}
}
private CancellationTokenSource _cts;
private void OnEnable()
{
_cts = new CancellationTokenSource();
StartAutoReturn(_cts.Token).Forget();
}
private void OnDisable()
{
_cts?.Cancel();
_cts?.Dispose();
_cts = null;
}
private async UniTaskVoid StartAutoReturn(CancellationToken token)
{
try
{
await UniTask.Delay(1000, cancellationToken: token);
ReturnToPool(); // ex: gameObject.SetActive(false);
}
catch (OperationCanceledException)
{
// 무시해도 됨
}
}
private void ReturnToPool()
{
gameObject.SetActive(false); // 또는 풀 시스템에 따라 반환
}
}
public class UIButtonHandler : MonoBehaviour
{
[SerializeField] Button _btn;
private CancellationTokenSource _cts;
void Awake()
{
_cts = new CancellationTokenSource();
// 버튼 클릭을 비동기로 처리 (UniTask 3.x 이상)
_btn.OnClickAsync(cancelToken: _cts.Token)
.ContinueWith(_ => Debug.Log("버튼 클릭됨"))
.Forget();
}
void OnDestroy()
{
// 클릭 대기 취소 및 해제
_cts.Cancel();
_cts.Dispose();
}
}
public class SceneSafeLoader : MonoBehaviour
{
async UniTaskVoid Start()
{
try
{
// 씬 전환으로 이 오브젝트가 파괴되면 이 토큰이 Cancel 돼요.
await LoadHeavyData(this.GetCancellationTokenOnDestroy());
Debug.Log("로딩 완료!");
}
catch (OperationCanceledException)
{
Debug.Log("씬 전환으로 로딩 취소됨");
}
}
async UniTask LoadHeavyData(CancellationToken token)
{
// 예: 긴 지연이나 웹 요청
await UniTask.Delay(TimeSpan.FromSeconds(10), cancellationToken: token);
// ... 추가 작업
}
}