[Unity] async/await 이용하여 팝업창에서 사용자 응답에 따른 분기 처리하기

지즈·2025년 6월 18일
0

Unity

목록 보기
16/17

동기와 비동기 개념

오늘 다룰 주제는 비동기 처리입니다. 특히, 유저 입력이나 서버 응답을 기다려야 하는 상황에서 async/await을 활용하는 방법에 대해 포스팅합니다. 우선 동기와 비동기의 차이점에 대해 간략히 설명하겠습니다.

동기(Synchronous) = 기다려야 하는 일

  • 데이터의 요청과 결과가 한 자리에서 동시에 일어납니다. 결과를 받을 때까지 다른 일을 할 수 없고, 반드시 기다려야만 합니다.
  • 요청 A를 하고 A 가 끝나야만 다른 작업을 시작할 수 있음 : 작업 B는 대기 상태
  • 예) 사용자가 서버에 데이터를 요청하면, 서버가 응답을 리턴해주기 전까지 사용자는 다른 활동을 할 수 없으며 기다려야 합니다.

비동기(Asynchronous) = 기다리지 않고 다른 일 가능

  • 요청한 결과는 동시에 일어나지 않을 거라는 약속과 같습니다.
  • 요청 A를 하고 바로 다른 작업 B로 넘어가고, 요청한 작업 A가 끝나면 프로그램은 콜백/이벤트 형태로 알려줍니다.
  • 예) 사용자가 서버에 데이터를 요청한 뒤, 응답을 계속 기다리지 않고 다른 작업을 수행하거나 서버에 다른 요청을 보내도 됩니다.


async/await 의 필요성

시간이 오래 걸리는 작업(예: 서버 통신, 파일 읽기, 사용자 입력 대기 등)을 메인 스레드를 멈추지 않고 처리하고 싶을 때 async/await를 사용합니다.

async/await 의 문법 기본 구조

public asyn Task<int> AsyncFunction()
{
	await Task.Delay(1000); // 1초 대기
	return 1020;
}
  • async: 이 함수는 비동기 함수임을 선언하며, 내부에서 await를 사용할 수 있게 합니다.
  • await: 비동기 작업이 끝날 때까지 논리적으로는 대기하지만, 실제로 스레드는 점유하지 않습니다.
    • 즉, await은 코드 흐름을 잠시 멈추는 것이지, CPU를 점유하거나 블로킹하는 것이 아닙니다.
    • await 뒤에는 Task 가 옵니다.
  • Task<int>: 이 함수는 비동기적으로 실행되며, 최종적으로 int 결과를 반환하는 Task 객체를 리턴함을 의미합니다.


응용 : 팝업 선택지 선택에 따라 다른 처리하기

게임 개발에서는 유저에게 어떤 선택을 하도록 유도하는 팝업 UI를 띄우고, 유저가 선택할 때까지 기다린 다음, 그에 따라 행동을 결정하는 경우가 많습니다. 이처럼 외부 입력을 기다렸다가 흐름을 재개하는 구조async/await는 매우 적합합니다.

CheckAbandonItem()을 호출하면:
1. 팝업을 띄우고
2. 유저가 "예"/"아니오"를 누를 때까지 기다렸다가
3. 선택 결과에 따라 분기 처리

비동기 호출 1 : AbandonItem() → await inventoryView.CheckAbandonItem()

    public async void AbandonItem(DraggableItem requester, Item item)
    {
		// 유저의 응답 대기하기 
        bool abandon = await inventoryView().CheckAbandonItem(item);
				
		// ==== CheckAbandonItem()이 bool 값을 처리하기 전까지 실행되지 않는다 ====
				
		// 유저 응답에 따른 분기 처리
        if (abandon)
        {
		    // 아이템을 버린다고 선택한 경우
            requester.ConfirmAbandonItem();
            controller().AbandonItem(item);
        }
        else
        {
		    // 아이템을 버리지 않겠다고 선택한 경우
            requester.CancelAbandonItem();
        }
    }

여기서 중요한 포인트는 await유저의 선택이 끝날 때까지 기다렸다가, 그 결과(bool abandon)를 받은 뒤 다음 로직을 수행한다는 것입니다. 코드 흐름은 마치 동기처럼 보이지만, 내부적으로는 비동기로 작동하여 메인 스레드를 멈추지 않습니다.

비동기 호출 2 : CheckAbandonItem() → await abandonDecision.Task

    public async Task<bool> CheckAbandonItem(Item item)
    {
		// 가이드 팝업을 띄운다
        guidePopup.SetPopupInfo($"{item.details.label} 아이템을\n버리시겠습니까?");
        guidePopup.ShowUI();
				
		// Task 생성하기
        abandonDecision = new TaskCompletionSource<bool>();        
				
		// abandonDecision의 Task가 완료되길 기다리기
		// 여기서 완료란, Task<T> 의 T 값을 설정하는 것이다. 
        return await abandonDecision.Task;
    }

    private void SetGuidePopupEvents()
    {
		// 버튼 클릭에 대한 이벤트 등록
        guidePopup.SetDynamicPopupEvent(OnClickGuidePopupConfrimBtn, OnClickGuidePopupCancelBtn);
    }

    private void OnClickGuidePopupConfrimBtn()
    {
		// abandonDecision Task의 값을 설정하여 작업을 완료시킨다.
        abandonDecision?.TrySetResult(true);
        // 팝업 닫기
        guidePopup.HideUI();
    }

    private void OnClickGuidePopupCancelBtn()
    {
    	// abandonDecision Task의 값을 설정하여 작업을 완료시킨다.
        abandonDecision?.TrySetResult(false);
        // 팝업 닫기 
        guidePopup.HideUI();
    }

이 함수는 팝업을 띄우고, TaskCompletionSource<bool> 로 비동기 작업을 생성한 후, 유저가 응답할 때까지 await을 통해 대기 상태에 진입합니다. 실제 값은 버튼 클릭 이벤트에서 설정됩니다.

return await abandonDecision.Task

여기서 abandonDecision.Taskawait을 만나 bool 값이 됩니다. 그러므로, 이 함수는 bool을 반환하는 것 같지만, 다시 컴파일러가 이를 Task<bool>로 감싸 반환합니다. async로 선언된 함수는 항상 Task<T>를 반환하기 때문입니다.


여기서 사용된 TaskCompletionSource 는 다음과 같습니다.

TaskCompletionSource

개발자가 직접 완료시킬 수 있는 Task<T>를 만드는 클래스입니다. 보통 Task는 시스템이 실행한 후 완료시켜주지만, TaskCompletionSource는 개발자가 수동으로 SetResult, SetException, SetCanceled를 호출해줘야 합니다.

메서드설명
.Task우리가 컨트롤할 Task 객체
.SetResult(value)작업을 성공적으로 종료하고 결과를 설정
.TrySetResult(value)위와 같지만, 이미 완료된 경우 예외를 발생시키지 않음
.SetException(e)작업 실패로 완료시키며 예외 전달
.SetCanceled()작업을 취소된 상태로 완료시킴

이 도구는 유저 입력, 서버 응답, 애니메이션 완료 등 외부 이벤트 기반의 작업을 비동기 흐름에 통합할 때 매우 유용합니다.


이처럼 코드를 작성하면, 사용자가 선택할 때까지 메인 스레드는 멈추지 않으면서도, 마치 동기처럼 기다릴 수 있게 됩니다.

이상입니다.

profile
클라이언트 개발자가 되는 그 날까지 킵 고잉

0개의 댓글