UniTask란?
코루틴과 비교
Unitask(=ASync/Await)
- 코루틴의 기능을 대체
메모리 누수
를 방지하기 위한 Task Tracker 윈도우
지원
장점1: 제로할당
: 힙 할당
이 발생하지 않음
장점2: 서버
로 받은 값을 리턴 가능
단점: 라이브러리
임포트 필요(프로젝트의 빵이 커짐)
Coroutine
설치 방법
git UPM
에 주소
복사
Unity Package
파일을 직접 적용
임포트 구문
using
UnitTask VS Coroutine 비교 설명
N초 지연
private IEnumerator Wait1Second(){
yield return new WaitForSeconds(1f);
Debug.Log("1 Seconds Passed");
}
private async UniTaskVoid Wait1SecondAsync(){
await UnitTask.Delay(1000);
await UnitTask.Delay(TimeSpan.FromSeconds(1f));
Debug.Log("1 Seconds Passed");
}
실행 방법
private void Start(){
StartCoroutine(Wait1Second());
Wait1SecondAsync().Forget();
}
TimeScale에 영향을 받지 않는 방법
private IEnumerator WaitForSecond(){
yield return new WaitForSecondsRealtime(1f);
}
private async UniTaskVoid Wait1SecondAsync(){
await UniTask.Delay(TimeSpan.FromSeconds(1f), DelayType.UnscaledDeltaTime);
}
private void Start(){
Time.timeScale = 0;
StartCoroutine(Wait1Second());
Wait1SecondAsync().Forget();
}
특정 조건 설정
[SerializedField]
private int _count;
private IEnumerator Wait3Count(){
yield return new WaitUntil(() => _count == 3);
Debug.Log("Count is 3");
}
private async UniTaskVoid Wait3CountAsync(){
await UniTask.WaitUntil(() => _count == 3);
Debug.Log("Count is 3");
}
private void Start(){
Wait3CountAsync().Forget();
}
이미지 가져오기
private const string AppleImagePath = "https://...";
public RawImage profileImage;
private IEnumerator WaitGetWebTexture(UnityAction<Texture> action)
{
UnityWebRequest request = UunityWebRequestTexture.GetTexture(AppleImagePath);
yield return request.SendWebRequest();
if(request.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(request.error);
}
else
{
Texture2D texture = ((DownloadHandlerTexture)request.downloadHandler).texture;
action.Invoke(texture);
}
}
private void Start()
{
StartCoroutine(WaitGetWebTexture(texture => {
protileImage.texture = texture;
}));
}
private async UniTask<Texture2D> WaitGetWebTextureAsync()
{
UnityWebRequest request = UnityWebRequestTexture.GetTexture(AppleImagePath);
await requst.SendWebRequest();
if(request.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(request.error);
}
else
{
Texture2D texture = ((DownloadHandlerTexture)request.downloadHandler).texture;
return texture;
}
return null;
}
private async UniTaskVoid GetImageAsync()
{
Texture2D texture = await WaitGetWebTextureAsync();
profileImage.texture = texture;
}
private void Start()
{
GetImageAsync().Forget();
}
종료 및 일시정지
코루틴
private Coroutine _coroutine;
private void Start()
{
_coroutine = StartCoroutine(Wait3Second());
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
StopCoroutine(_coroutine);
}
}
private IEnumerator Wait3Second()
{
yield return new WaitForSeconds(3f);
Debug.Log("3 seconds passed");
}
UniTask
- CancellationTokenSource(): Cancel 타이밍을 원할 때 처리 가능, 직접적인 Dispose 호출 필요
source의 메모리
는 자동
으로 해제
되지 않음
- Dispose
를 통해 수동으로 메모리 해제 필요
private CancellationTokenSource _source = new();
private void Start()
{
Wait3Second().Forget();
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
_source.Cancel();
}
}
private UniTaskVoid Wait3SecondAsync()
{
await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken: _source.Token);
Debug.Log("3 seconds passed");
}
private void OnDestroy()
{
_source.Cancel();
_source.Dispose();
}
private void OnEnable()
{
if(+source != null)
{
_source.Dispose();
}
_source = new();
}
private void OnDisable()
{
_source.Cancel();
}
- TokenSource
메모리
수동
관리는 귀찮...
- 이를 자동으로 만드는 방식도 개발해두었다.
this.GetCancellationTokenOnDestroy()
: Destroy될 때 Cancel 및 Dispose 수행
- [★]단 오브젝트가
비활성
된 경우에는, 계속 메모리에 할당됨
private async UniTaskVoid Wait3Second()
{
await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken: this.GetCancellationTokenOnDestroy());
Debug.Log("3 seconds passed");
}
Task Tracker[★]
코루틴
에 없던 기능이라 매우 중요
- 매우
편함
Unity
-> Window
-> UniTask Tracker
-> 진행중인 모든 Task
확인 가능
- 매우 강력 및 편함
private void Start()
{
Wait3Second().Forget();
}
private async UniTaskVoid Wait3Second()
{
await UniTask.Delay(TimeSpan.FromSeconds(3f), cancellationToken : this.GetCancellationTokenOnDestroy());
Debug.Log("3 seconds passed");
}
DOTween 호완
Edit
-> ProjectSettings
-> Player
-> Other Settings
-> Script Define Synbols
-> + -> 공식 문서 내용(UNITASK_DOTWEEN_SUPPORT
)를 넣기 -> Apply
버튼
간단한 UniTask + DOTween 혼용
private void Start()
{
WaitMove().Forget();
}
private async UniTaskVoid WaitMove()
{
await.transform.DOMove(new Vector3(0, 3, 3), 3f);
Debug.Log("XYZ(0,3,0) 위치로 이동 완료");
}