System - SceneManager

최강산·2023년 8월 20일
0

클래스 설명

Class SceneManager

  • 씬을 로드하거나 삭제 등 관리하는 역할을 한다.
  • 각 씬들은 Define 클래스에 Enum으로 관리 했다.

이번 SceneManager는 MonoBehaviour가 있어야 관리하기 편하기 때문에
싱글톤으로 따로 만든 후 Managers를 통해서 접근 하도록 만들겠다.






로직 설명

Singleton

private static SceneManager instance;
public static SceneManager Instance { get { return instance; } }

[RuntimeInitializeOnLoadMethod]
private static void Init()
{
    GameObject go = GameObject.Find($"[{nameof(SceneManager)}]");
    if(go == null)
        go = new GameObject { name = $"[{nameof(SceneManager)}]" };
    instance = go.GetOrAddComponent<SceneManager>();
    DontDestroyOnLoad(go);

    UnityEngine.SceneManagement.SceneManager.sceneLoaded += instance.LoadedScene;
    instance.LoadedScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene(), UnityEngine.SceneManagement.LoadSceneMode.Single);
}
  • 런타임 초기화시 Init() 실행

  • 이미 SceneManager가 Scene안에 있는지 체크 후 없다면 생성

  • UnityEngine.SceneManagement.SceneManager.sceneLoaded 이벤트에 LoadedScene()함수 체인

  • DontDestroyOnLoad() 실행 및 현재 씬 관리 함수 호출






LoadScene

public void LoadScene(Define.Scene _scene)
{
    string sceneName = _scene.ToString();
    UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
}
  • 매개변수로 받은 Scene enum값을 스트링값으로 변환

  • 변환한 값으로 UnityEngine.SceneManager.LoadScene() 실행






LoadedScene

private void LoadedScene(UnityEngine.SceneManagement.Scene _scene, UnityEngine.SceneManagement.LoadSceneMode _loadSceneMode)
{
    RemoveScene(currentScene, () => 
    {
        currentScene = _scene.name;
        AddScene(_scene.name);
    });
}
  • 현재 씬을 관리중인 씬 클래스 삭제

  • 씬이 삭제되면 새로 켜진 씬을 관리하는 씬 클래스 부착






AddScene

public void AddScene(string _sceneName)
{
    BaseScene bs = null;
    Define.Scene addScene = Util.ParseEnum<Define.Scene>(_sceneName);
    switch(addScene)
    {
        case Define.Scene.Loading:
            bs = gameObject.AddComponent<LoadingScene>();
            break;

        case Define.Scene.Guild:
            bs = gameObject.AddComponent<GuildScene>();
            break;

        case Define.Scene.IceDungeon:
            bs = gameObject.AddComponent<IceDungeonScene>();
            break;
    }
    bs.Init();
}
  • 매개변수로 받은 값을 Enum으로 parse

  • parse한 값에 맞는 씬 관리 클래스 부착

  • 부착한 씬 관리 클래스 초기화






RemoveScene

public void RemoveScene(string _sceneName, System.Action _callback = null)
{
    if(string.IsNullOrEmpty(_sceneName))
    {
        _callback?.Invoke();
        return;
    }

    BaseScene bs = null;

    Define.Scene removeScene = Util.ParseEnum<Define.Scene>(_sceneName);
    switch (removeScene)
    {
        case Define.Scene.Loading:
            bs = gameObject.GetComponent<LoadingScene>();
            break;

        case Define.Scene.Guild:
            bs = gameObject.GetComponent<GuildScene>();
            break;

        case Define.Scene.IceDungeon:
            bs = gameObject.GetComponent<IceDungeonScene>();
            break;
    }

    bs.Clear();
    Destroy(bs);
    _callback?.Invoke();
}
  • 이전에 씬이 있었는지 확인 후 없다면 리턴 and 콜백

  • 매개변수로 받은 값을 Enum으로 parse (오타 나지 않기 위해?)

  • parse한 값에 맞는 씬 관리 클래스 삭제

  • 부착한 씬 관리 클래스 초기화 후 삭제

  • 콜백






ETC

Enum Scene

public enum Scene
{
    Loading,
    Guild,
    IceDungeon
}

Class BaseScene

public abstract class BaseScene : MonoBehaviour
{
    public abstract void Init();
    public abstract void Clear();
}
profile
나 왜 아직도 초보 개발자?

0개의 댓글

관련 채용 정보