Unity - Reactive Programming 1

땡구의 개발일지·2025년 8월 21일

Unity마스터

목록 보기
75/78
post-thumbnail

오늘은 Reactive 프로그래밍과 관련된 것들을 배운다.

  1. 비동기 쓰레드처럼 동작하던 코루틴을 대체하는 기능인 UniTask
  2. 절차지향, 객체지향같은 프로그래밍 패러다임 중 하나인 Reactive 프로그래밍을 유니티에서 가능케 하는 라이브러리인 UniRx
  3. 종속성 주입으로 사용되는 Zenject 오픈소스 깃허브 기능이다.

오늘은 비동기 함수를 수행하는 코루틴과 그것을 대체하는 UniTask를 알아본다.


🔁 Coroutine

기존에 사용하던 로직 분산 처리 기법. async/await 처럼 멀티 쓰레드를 사용하는 방식은 아니다. 실제로는 싱글 쓰레드로 전부 작업된다.

  1. 객체 생성 방식이다. 이 때문에 메모리 누수 문제가 있다. 객체를 생성하고, 삭제도 해야 하기 때문에 코드가 난잡해지는 문제도 있다.
  2. 앞서 말한대로 실제로는 멀티 쓰레드가 아니기 때문에, 성능 문제가 있다.

이러한 단점을 보완하고 나온 것이 UniTask다.


💥 UniTask

비동기식 프로그래밍, 리액티브 프로그래밍에 적합한 비동기식 로직 분산 처리 기능이다. 실제로 멀티쓰레드로 동작한다.

  1. 메모리에 유리하다
  2. 유니티의 모든 async/await 코루틴을 대체한다.

원래는 유니티 상에서는 async/await가 적절한 처리 방식이 아니다. 라이프 사이클 때문이다.

private async Task test()
{
	await testFunction(); // 이렇게 하면 끝날 때까지 기다림
}

위와 같은 코드가 그냥 Unity에서는 되지 않는다.

📌 사용법

이제 UniTask를 어떻게 사용하는 지 알아보자

🔧 카운트 다운

  • Coroutine
private void Update()
{
	if(Input.GetKeyDown(KeyCode.Space))
    {
    	Coroutine routine = StartCoroutine(CountDownRoutine());
    }
}
IEnumerator CountDownRoutine()
{
	WaitForSeconds wait = new WaitForSeconds(1f);
    
    for(int count = 5; count >= 1; count --)
    {
    	Debug.Log(count);
    	yield return wait;
    }
}

코루틴은 반환도 코루틴이다.

  • UniTask
    UniTask는 반환형을 가질 수 있다. void형을 반환하고자 한다면, UniTaskVoid로 넣으면 된다.
private void Update()
{
	if(Input.GetKeyDown(KeyCode.Space))
    {
    	bool result = CountDownTask();
    }
}
private async UniTask<bool> CountDownTask()
{
	for(int count = 5; count >= 1; count--)
    {
    	Debug.Log(count);
    	await UniTask.WaitForSeconds(1f);
    }
	return true;
}

UniTask는 구조체이기 때문에, 스택영역에서 형성된다. 그러므로 가비지 컬렉션이 작동하지 않는다.

🔧 비동기식 함수

  • Coroutine
yield return FirebaseApp....();
  • UniTask
await FirebaseApp....();

🔧 병렬 작업

코루틴의 경우, 분산 처리를 할 때 하나하나 끝날 때까지 기다려야 된다. CSV를 링크를 통해 전부 받는다 해보자.

  • Coroutine
var task 1 = UnityWebRequest.Get("");
var task 2 = UnityWebRequest.Get("");
var task 3 = UnityWebRequest.Get("");

yield return task1;
yield return task2;
yield return task3;
  • UniTask
    UniTask는 병렬 작업이 전부 끝날 때 까지 기다릴 수 있다.
var task1 = GetTextAsync(UnityWebRequest.Get(path));
var task2 = GetTextAsync(UnityWebRequest.Get(path));
var task3 = GetTextAsync(UnityWebRequest.Get(path));

await UniTask.WhenAll(task1, task2, task3);
profile
개발 박살내자

0개의 댓글