최근 작업중인 게임 데이터를 Local에 저장하던 것을 Firebase의 Database로 옮기는 작업을 진행하고 있다. DB에 데이터 저장은 잘되는데 Load가 제대로 되질 않아 삽질을 했던 경험을 공유하고자 한다.
내 프로젝트의 GameManager는 게임을 시작할 때 게임의 구성을 갖추는 셋팅을 할 때 IEnumerator 함수를 통해 플레이어를 생성 및 초기화하고 게임을 구성한다. Firebase에서 데이터를 가져오기 위해 FirebaseManager에 접근해 데이터를 로드하는 async 함수를 실행하면 Unity가 작동을 멈췄다.
Unity의 IEnumerator 함수안에서 async 사용시 응답없음 문제가 발생하는 이유는 IEnumerator 함수가 Deferred Execution을 사용하기 때문입니다. Deferred Execution은 CPU에서 현재 실행 중인 코드를 일시 중단하고 다른 작업을 수행한 다음, 다시 원래 코드를 실행하는 방식입니다.
IEnumerator 함수안에서 async 사용시, 코루틴이 비동기 작업을 수행하기 시작하면, IEnumerator 함수는 일시 중단됩니다. 이때 Unity의 UI, 물리, 입력 등의 시스템은 계속 실행되지만, 게임의 로직은 일시 중단됩니다.
만약 IEnumerator 함수안에서 async 사용시 비동기 작업이 오래 걸리면, Unity의 UI, 물리, 입력 등의 시스템은 계속 실행되지만, 게임의 로직은 일시 중단된 상태로 유지됩니다. 이로 인해 게임이 응답없음 상태가 됩니다.
Unity의 IEnumerator 함수안에서 async 사용시 응답없음 문제를 해결하는 방법
Unity의 IEnumerator 함수안에서 async 사용시 응답없음 문제를 해결하려면 다음과 같은 방법을 사용할 수 있습니다.
- YieldInstruction을 사용하여 비동기 작업이 완료될 때까지 기다립니다.
- async/await 키워드를 사용하여 비동기 작업을 수행합니다.
YieldInstruction을 사용하여 비동기 작업이 완료될 때까지 기다리는 방법
using System.Collections;
using UnityEngine;
public class GameManager : MonoBehaviour
{
FirebaseManager firebaseManager;
IEnumerator GetUserCoroutine()
{
// 비동기 작업을 수행합니다.
var task = firebaseManager.GetUser();
// 비동기 작업이 완료될 때까지 기다립니다.
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null)
{
// 에러 처리
Debug.LogError(task.Exception);
}
else
{
// 게임 로직 실행
var user = task.Result;
Debug.Log("User: " + user);
}
}
}
이 예제에서는 firebaseManager.GetUser() 메서드를 사용하여 비동기 작업을 수행합니다. GetUser() 메서드는 Firebase의 데이터베이스에 있는 사용자 정보를 가져오는 작업입니다.
GetUser() 메서드가 완료될 때까지 기다리기 위해 WaitUntill 코루틴를 사용합니다. WaitUntill 코루틴에서 task.IsCompleted 속성을 사용하여 비동기 작업이 완료되었는지 확인합니다.
결론
Unity에서 하나의 비동기 함수에서 또 다른 비동기 함수를 호출하는것을 자제하는 것이 좋습니다.
'Unity > Tip' 카테고리의 다른 글
Unity에서 csv파일 만들기 (2) | 2023.11.01 |
---|---|
Unity에서 게임 오브젝트의 Null 체크 속도 비교 (0) | 2023.10.30 |
클릭한 위치가 특정 오브젝트 안에 속해 있는지 판단하는 방법 (0) | 2023.10.04 |
Animation Preview Auto Play (0) | 2023.09.11 |
~~~ is missing the class attribute 'ExtensionOfNativeClass'! (0) | 2023.08.21 |