반응형
Unity에서 비동기 처리는 필수적인 개념인데 오늘은 이것의 개념을 다시 한번 정리해볼겸 작성해봤다.
대표적인 방법은 크게 두 가지가 떠오를텐데 바로 Async/Await과 Coroutine이다.
이 두 방식은 비슷해 보이지만 동작 방식과 적용할 수 있는 상황이 다르다!!
개념과 특징, 예시를 정리해보자
1. Async/Await
(1) 개념
C#의 비동기 프로그래밍 기능을 활용하는 방식으로 주로 네트워크 요청, DB 연동, 파일 입출력 등의 CPU 또는 I/O 바운드 작업에 사용된다
(2) 특징 및 예시
(2-1) Unity 엔진을 직접 조작할 수 없다
public class AsyncAwaitExample : MonoBehaviour
{
void Start()
{
RunAsyncOperations();
}
async void RunAsyncOperations()
{
Debug.Log("Start Test!!!!");
await TestUnityEngineAccess();
}
async Task TestUnityEngineAccess()
{
try
{
await Task.Run(() =>
{
transform.position = new Vector3(10, 0, 0);
});
}
catch (Exception ex)
{
Debug.LogError($"Error Message : {ex.Message}");
}
}
}
: Unity 엔진을 직접 조작을 시도했을 때 아래와 같은 에러가 발생한다
(2-2) try-catch를 활용해 예외 처리가 가능하다
public class AsyncAwaitExample : MonoBehaviour
{
void Start()
{
RunAsyncOperations();
}
async void RunAsyncOperations()
{
Debug.Log("Start Test!!!!");
await HandleExceptionAsync();
}
async Task HandleExceptionAsync()
{
try
{
Debug.Log("네트워크 요청 시뮬레이션...");
await SimulateNetworkRequest();
}
catch (Exception ex)
{
Debug.LogError($"예외 발생: {ex.Message}");
}
}
async Task SimulateNetworkRequest()
{
await Task.Delay(1000); // 네트워크 요청 시뮬레이션
throw new Exception("네트워크 연결 실패!");
}
}
: SimulateNetworkRequest()에서 강제로 예외를 발생 => try-catch를 사용하여 예외를 안전하게 처리!
(2-3) CancellationToken을 사용하면 비동기 작업을 취소할 수 있다!
public class AsyncAwaitExample : MonoBehaviour
{
private CancellationTokenSource _cancellationTokenSource;
void Start()
{
_cancellationTokenSource = new CancellationTokenSource();
RunAsyncOperations();
}
async void RunAsyncOperations()
{
Debug.Log("Start Test!!!!");
await TaskWithCancellation(_cancellationTokenSource.Token);
}
async Task TaskWithCancellation(CancellationToken cancellationToken)
{
Debug.Log("5초간 작업 수행 중... (취소 가능)");
try
{
for (int i = 0; i < 5; i++)
{
if (cancellationToken.IsCancellationRequested)
{
Debug.LogWarning("작업 취소됨!");
return;
}
Debug.Log($"진행 중임... {i + 1}초 경과");
await Task.Delay(1000, cancellationToken);
}
Debug.Log("작업 끝!");
}
catch (TaskCanceledException)
{
Debug.LogWarning("작업이 강제로 취소됨!");
}
}
void OnDestroy()
{
// 게임 종료 시 작업 취소
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
}
}
: 오브젝트가 Destory 될 때 _cancellationTokenSource.Cancel();을 호출되면서 작업이 취소됨!
(2-4) 멀티스레드 활용이 가능하다!
2. Coroutine
(1)개념
: Unity 엔진 메인 스레드에서 실행되며, 프레임 단위로 코드를 실행할 수 있다.
즉 게임 루프와 직접적으로 연결되며, 프레임 단위로 코드 실행을 멈췄다가 다시 실행할 수 있는 기능이 있다!
(2) 특징 및 예시
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
//(2-1) 메인 스레드에서 실행되기 때문에 GameObject, Transform, UI 등을 직접 조작할 수 있다.
//(2-2) 특정 시간 동안 대기(Wait) 후 실행할 수 있음 (WaitForSeconds, WaitUntil 등)
//(2-3) StopCoroutine()을 사용하면 중단 가능하지만, 종료 후에는 재개할 방법이 없음
//(2-4) Unity가 종료되면 자동으로 중단됨
public class CoroutineExample : MonoBehaviour
{
public GameObject cube; // 움직일 오브젝트
public Text statusText; // UI 텍스트
private Coroutine moveCoroutine; // 코루틴 핸들 저장
void Start()
{
moveCoroutine = StartCoroutine(MoveCubeCoroutine());
}
IEnumerator MoveCubeCoroutine()
{
while (true)
{
cube.transform.position += Vector3.right * 0.1f; // (2-1) GameObject 직접 조작
yield return new WaitForSeconds(0.5f); // (2-2) 0.5초마다 이동
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (moveCoroutine != null)
{
// (2-3) StopCoroutine()을 사용하여 중단 (다시 실행 불가)
StopCoroutine(moveCoroutine);
moveCoroutine = null;
}
}
}
void OnApplicationQuit()
{
// (2-4) Unity가 종료되면 자동으로 중단됨
Debug.Log("Unity 종료 - 모든 코루틴 자동 중단됨");
}
}

Async/Await을 사용하는 경우
- 네트워크 요청 (서버에서 데이터 가져오기, API 호출)
- 파일 입출력 (로컬 데이터 저장/로드)
- 데이터베이스 연동 (Firebase, SQLite)
- Unity 엔진과 무관한 백그라운드 작업
Coroutine을 사용하는 경우
- 게임 내에서 프레임 단위로 실행해야 하는 작업
- 애니메이션, UI 효과, NPC 움직임, 특정 시간 후 실행되는 로직
- Unity의 메인 스레드에서 실행해야 하는 작업
반응형
'Unity 개발 > 기술 향상' 카테고리의 다른 글
[Unity] ScriptableObject 개념 정리 (0) | 2025.03.04 |
---|---|
[Unity] Unity에서 DLL과 Assembly Definition을 활용한 최적화 전략 (0) | 2025.03.03 |
[Unity] Google 계정 로그인 연동 (1) | 2024.12.21 |
[Unity] SHA 인증서 가져오기 (릴리즈 배포 환경 인증용) (0) | 2024.12.02 |
[Unity] SHA 인증서 가져오기 (테스트 환경) (0) | 2024.12.01 |