Unity - 네트워크 팀프로젝트 5

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

Unity마스터

목록 보기
69/78

비동기 씬 로드

씬을 로딩한 이후의 작업을 시키려고 다음과 같이 코드를 짜면 의도한 바 대로 작동하지 않는다.

SceneManager.LoadScene("LoginScene");
Manager.Net.roomManager = FindObjectOfType<RoomManager>();
Manager.Net.roomManager.RoomReInit();

LoadScene 이후에 작성된 코드들은 무시될 수 있다. 이후에 바로 코드에 명령어를 추가하면, roomManager가 null이 된다.

이유

  1. SceneManager.LoadScene("LoginScene") 이후 코드는 즉시 실행된다.
  2. 하지만, 씬 로딩은 LoadSceneAsync와 다르게 비동기적으로 처리되지 않고 한 프레임 뒤에 완료된다. 해당 프레임에서는 코드 수행 시작과 함께 다음 줄의 코드로 넘어간다.
  3. 즉, LoadScene()이 호출되면 현재 프레임 끝에 다음 씬으로 전환되고, 그 전에 바로 다음 줄이 실행돼서 FindObjectOfType<RoomManager>() 는 null이 되는 것이다.

해결 방법

이 문제를 해결하려면, 씬을 비동기로 로드해오고 작업이 완료 됐을 때의 이벤트에 수행할 내용을 넣어야 한다.

private void ChangeToLoginScene()
{
    AsyncOperation async = SceneManager.LoadSceneAsync("LoginScene");
    if (async != null)
        async.completed += (AsyncOperation op) =>
        {
            Manager.Net.roomManager = FindObjectOfType<RoomManager>();
            Manager.Net.roomManager.RoomReInit();
        };
}

다른 방법

  1. 씬이 로딩 된 후, 다음 프레임에 수행 로직을 넘기기
    yield return null을 하게 되면, 한 프레임을 넘어가는 것을 이용한 방법이다.
StartCoroutine(LoadSceneAndInit());

IEnumerator LoadSceneAndInit()
{
    SceneManager.LoadScene("LoginScene");
    yield return null; // 한 프레임 대기 (씬이 완전히 전환됨)

    Manager.Net.roomManager = FindObjectOfType<RoomManager>();
    Manager.Net.roomManager.RoomReInit();
}
  1. sceneLoaded 사용하기
    이벤트 형식으로 처리하는 방법이다.
void Start()
{
    SceneManager.sceneLoaded += OnSceneLoaded; // 구독 등록
    SceneManager.LoadScene("LoginScene");
}

void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
    if (scene.name == "LoginScene")
    {
        Manager.Net.roomManager = FindObjectOfType<RoomManager>();
        Manager.Net.roomManager.RoomReInit();

        SceneManager.sceneLoaded -= OnSceneLoaded; // 구독 해제
    }
}
profile
개발 박살내자

0개의 댓글