<유니티> 비동기 로딩 씬 구현

상태
시작 전
담당자
날짜
숫자
0
여러분. 게임을 하다 보면 다음 씬으로 넘어갈 때 로딩 화면을 보며 기다릴 때가 있을 겁니다. 게임을 개발할 때 로딩 시간은 중요한 요소 중 하나입니다. 특히 큰 씬을 로드하거나 리소스가 많이 필요한 경우, 로딩 화면이 필수적입니다. 로딩 화면은 단순한 시각적 요소일 뿐만 아니라, 게임의 몰입도를 높이는 중요한 역할을 합니다. 유니티에서는 일반적인 로딩 씬과 비동기 로딩을 활용한 로딩 씬을 구현할 수 있습니다. 이번 글에서는 두 방식의 차이점과 구현 방법을 설명하며, 왜 비동기 로딩이 더 나은 선택일 수 있는지 살펴보겠습니다.

일반적인 로딩 씬 구현

일반적인 로딩 씬은 하나의 씬을 로드할 때 발생하는 지연 시간을 줄이는 방법 중 하나로, 유저에게 게임이 진행되고 있다는 신호를 주기 위해 사용됩니다. 기본적으로 유니티의 SceneManager.LoadScene()을 사용하여 다음 씬을 불러오면, 현재 씬이 멈추고 새로운 씬이 로드될 때까지 기다리게 됩니다. 이는 동기적 방식으로 로딩 씬을 구현한 것인데요. 아래 예시 코드를 보며 알아보겠습니다.
using UnityEngine; using UnityEngine.SceneManagement; public class LoadSceneExample : MonoBehaviour { void Start() { } void Update() { if(Input.GetKeyDown(KeyCode.Space)) { // 2번 씬을 로드합니다. 현재 씬이 멈추고 로딩이 완료될 때까지 기다립니다. SceneManager.LoadScene("Scene2"); } } }
C#
복사
위의 코드는 스페이스바를 누르게 되면 다음 씬으로 넘어가는 코드입니다.
일단 씬 전환을 하기 위해서는 UnityEngine.SceneManagement; 라는 네임스페이스를 사용해야합니다. 그 이후 SceneManager.LoadScene() 을 사용하여 다음 씬을 불러오죠.

비동기 로딩 씬이 유리한 이유

위의 코드와 같이 동기적으로 처리하게 되면 로딩 화면 처리가 끝난 이후, 다음 씬의 리소스를 가져올 것입니다. 그렇다면 플레이어 입장에서는 결국 로딩 화면이 끝나고 검은 화면을 보고 기다리게 될 것입니다.
그래서 우리는 비동기 로딩을 사용하게 됩니다. 만약 이를 비동기적으로 처리하게 된다면, 일반적으로 빠르게 처리할 수 있는 로딩 화면을 먼저 보여주고, 로딩 창을 보여주는 동안 다음 씬의 리소스를 불러올 것입니다.
그렇다면 어떤 식으로 비동기 로딩 씬을 구현하는지 알아보겠습니다.

비동기 로딩 씬 구현

이 방식은 SceneManager.LoadSceneAsync()를 사용하여 구현할 수 있으며, 로딩 진행 상태를 보여줄 수 있기 때문에 사용자 경험을 크게 개선할 수 있습니다.
using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class LoadingSceneController : MonoBehaviour { static string nextScene; [SerializeField] Image progressBar; public static void LoadScene(string sceneName) { nextScene = sceneName; SceneManager.LoadScene("LoadingScene"); } void Start() { StartCoroutine(LoadSceneProgress()); } IEnumerator LoadSceneProgress() { AsyncOperation op = SceneManager.LoadSceneAsync(nextScene); op.allowSceneActivation = false; float timer = 0f; while (!op.isDone) { yield return null; if (op.progress < 0.9f) { progressBar.fillAmount = op.progress; } else { timer += Time.unscaledDeltaTime; progressBar.fillAmount = Mathf.Lerp(0.9f, 1f, timer); if (progressBar.fillAmount >= 1f) { op.allowSceneActivation = true; yield break; } } } } }
C#
복사