Class SceneManager
이번 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한 값에 맞는 씬 관리 클래스 삭제
부착한 씬 관리 클래스 초기화 후 삭제
콜백
Enum Scene
public enum Scene
{
Loading,
Guild,
IceDungeon
}
Class BaseScene
public abstract class BaseScene : MonoBehaviour
{
public abstract void Init();
public abstract void Clear();
}