개발/유니티 게임 개발

유니티 씬 전환

솔레이 2024. 3. 4. 07:51

 

1. Scene

씬은 쉽게 말하면 게임의 맵이다.

어떤 게임은 하나의 맵에서만 이야기가 진행이 되고, 어떤 게임은 여러 맵을 돌아다니며 게임을 진행하게 된다.

마찬가지로 게임을 개발할 때는 하나의 씬에서 제작이 될 때도 있지만 여러개의 씬으로 나누어서 제작이 진행되기도 한다.

간단한 게임의 경우 하나의 씬으로 개발해도 문제가 없지만 리소스의 규모가 커질 경우 게임의 동작이 무거워질 수도 있다.

때문에 대부분의 게임은 여러개의 씬으로 나누어서 개발을 진행한다.

 

2. Build Settings

게임 개발에 필요한 여러 개의 씬을 만들어두었다면 그 씬들을 불러놓을 필요가 있다. 

먼저 File > Build Settings 에 들어간다.

Build Settings에 들어간다면 Add Open Scenes 버튼을 눌러 현재 편집 중인 씬들을 빌드 목록에 넣어둘 수 있다.

씬을 불러올 경우 0번부터 인덱싱이 되며 Scene Load를 할 때 해당 인덱스를 사용해서 Load 할 수도 있다.

씬을 불러왔다 삭제를 할 경우 위의 이미지처럼 Deleted라고 함께 뜨니 Build Settings에서 꼭 지워주자.

 

3. Scene Load

- 사용 네임스페이스

using UnityEngine.SceneManagement;

 

Scene을 불러올 때는 크게 동기화 방식과 비동기화 방식으로 2가지 방식이 있다.

  • 동기화 방식
SceneManager.LoadScene( "SceneName", LoadSceneMode.Single);

현재 Scene을 종료하고 다음 Scene을 불러온다.

크기가 작아 바로 불러올 수 있는 Scene들에 사용된다.

 

  • 비동기화 방식
SceneManager.LoadScene( "SceneName", LoadSceneMode.Addictive);

현재 Scene을 종료하지 않고 다른 Scene을 추가로 불러온다.

여러 개의 Scene을 동시에 사용해야 하는 경우 사용된다.

 

SceneManager.LoadScene(0);
SceneManager.LoadScene("MainScene");

LoadScene에는 Scene name 혹은 Build Setting에서 지정되었던 인덱스로 불러올 수 있다.

LoadSceneMode를 지정하지 않을 경우 동기화 방식으로 Scene을 불러온다.

 

4. LoadSceneAsync

보통 게임을 플레이 하면 가장 많이 보게 되는 화면 중 하나는 로딩 화면이다.

 

게임에서 Scene을 전환할 때 다음 Scene의 크기가 클 경우 화면이 멈춰버린다.

보통 화면이 멈춘다면 사람들은 게임이 비정상적으로 작동하는 줄 알고 게임을 종료해버릴 것이다.

때문에 정말 가벼운 게임이 아니라면 로딩 화면이 없는 게임은 거의 없다.

 

이 로딩 화면을 만들 때 가장 보편적으로 사용하게 되는 명령어가 LoadSceneAsync이다.

LoadSceneAsync를 이용하면 비동기화 방식으로 화면을 로드하며 로딩 화면을 만드는데 필요한 요소를 얻게 된다.

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LoadingSceneManager : MonoBehaviour
{    
    private void Start()
    {
        StartCoroutine(LoadScene());
    }

    public void LoadScene()
    {
        SceneManager.LoadScene("LoadingScene");
    }

    IEnumerator LoadScene()
    {

        AsyncOperation loading = SceneManager.LoadSceneAsync("MainScene");
        loading.allowSceneActivation = false;
        float loadingprogress = 0.0f;
        while (!loading.isDone)
        {
            yield return null;
            if(loading.progress>loadingprogress)
            {
            	loadingprogress+=0.1f;
            	Debug.Log(loading.progress);
            }
            if(loadingprogress == 1.0f)
            {
            	loading.allowSceneActivation = true; 
                yield break;
            }

        }
    }
}

 

로딩 화면을 Coroutine을 이용해 필요할 때만 불러오도록 하며 로딩 진척도를 Debug log를 통해 알려준다.

로딩 진척도를 전부 알려주기 전에는 로딩이 완료되어도 Scene이 전환되지 않는다.

 

while (!loading.isDone)

isDone을 사용하면 로딩 완료 시 TRUE, 미완료시 FALSE를 반환한다.

때문에 해당 코드에서 IEnumerator는 기본적으로 로딩이 완료 될 때까지 루프한다.

 

loading.allowSceneActivation = true/false;

 

allowSceneActivation이 false인 경우 로딩이 완료되어도 해당 Scene으로 바로 이동하지 않는다.

로딩 프로그래스가 전부 올라가지 않았는데 다음 Scene으로 넘어가도 황당할테니 로딩 프로그래스가 전부 올라가고 난 후에 창이 변환되도록 한다.

 

이 코드를 응용해 Debug log 대신 이미지나 텍스트로 나타나게 되면 우리가 보통 보게 되는 로딩 화면이 완성된다.