35시간 무수면의 최후
다신 밤샘 작업은 하지 말아야지...
SceneManagerEx
동적 생성을 하기위해 꼭 필요한 것이 하나 있다면
그건바로 씬을 이동할 때 해당 씬 초기에 필요한 것 들을 불러주는 오브젝트 라고 할 수 있다.
A 씬에서 필요한 것들이 B 씬에선 필요가 없을 수도 있고 전혀 다른 오브젝트들을 소환할 수 있다.
이를 위해서
씬을 관리할 SceneManagerEx와 해당씬에 대한 정보를 가진 BaseScene 클래스가 필요하다.
어차피 유니티에서 자체적으로 SceneManager를 지원하고 씬을 전환할 수 있는데 왜 굳이 씬 매니저를 만드는가 싶지만
그 부분을 지금부터 알아보자.
먼저 앞서 말했듯 필요한 다른 것들을 불러주기위한 선발대 오브젝트가 필요하다.
그 역할을 @Scene 오브젝튿가 담당한다
해당 오브젝트는 BaseScene을 상속받은 각각의 자신의 씬 클래스를 가지고 있는데 현재 씬이 Title 이니
TitleScene 컴포넌트를 가지고있다.
그럼 이제 SceneManagerEx 를 보도록 하자.
public class SceneManagerEx
{
public BaseScene CurrentScene => UnityEngine.Object.FindObjectOfType<BaseScene>();
public void LoadScene(Define.Scenes scene)
{
Managers.Clear();
SceneManager.LoadScene(GetSceneName(scene));
}
private string GetSceneName(Define.Scenes scene)
{
string sceneName = System.Enum.GetName(typeof(Define.Scenes), scene);
return sceneName;
}
public void Clear()
{
CurrentScene.Clear();
}
}
씬 매니저의 전체 코드이다.
코드 내용을 살펴 보면 먼저 현재 씬이 어떤 씬인지 알 수 있는 CurrentScene get 프로퍼티가 있다.
현재 씬에 있는 BaseScene 을 찾아 현재 씬이 무엇인지 확인하는 구조이다.
그리고 실제 씬을 로드하는 Define.Scenes enum을 매개변수로 받는 LoadScene 함수가 있다.
public enum Scenes
{
None,
Title,
Main,
Dungeon,
Ending,
}
enum Scenes 에는 실제 사용될 씬이 들어있다.
예전 UI 자동화 때 썻던 방식과 비슷하게 실제 씬과 같은 이름이어야한다.
그 이유는 LoadScene을 하는 로직을 보면
유니티가 지원하는 SceneManager.LoadScene 에 씬 이름(string) 을 넘겨주는 부분에 Enum.GetName을 이용하기 때문.
이렇게 하면 하드코딩을 하지 않고 enum 값만 넘겨주면 된다.
그리고 Clear 함수를 이용하여 실제 현재 씬이 넘어갈 때 호출할 것 들을 적어주면 되는데
이번 프로젝트에선 Managers에 다른 모든 Manager들의 Clear를 넣어주고
씬이 넘어가는 LoadScene에서 호출하는 것으로 만들었다.
Managers.Clear();
LoadScene을 할 때 Managers.Clear 를 호출하는데 이 때 SceneManager의 Clear도 같이 호출이 된다.
그럼이제 Base 씬을 살펴 보도록 하자.
public class BaseScene : MonoBehaviour
{
public Define.Scenes SceneType { get; protected set; }
private void Awake()
{
Init();
}
protected virtual void Init()
{
EventSystem eventSys = FindObjectOfType<EventSystem>();
if (eventSys == null)
Managers.RM.Instantiate("UI/@EventSystem");
}
public virtual void Clear() { }
}
자신의 씬을 나타내는 SceneType 프로퍼티와
씬이 시작될 때 실행되는 Init 함수가 있다.
Init 에선 현재 씬에 EventSystem이 있는지 확인하여 없으면 미리 프리팹화 시켜둔 EventSystem을 생성한다.
또한 Init은 virtual 로 만들어 BaseScene을 상속받는 Scene들이 자신의 씬이 무엇인지 프로퍼티 set을 하고,
씬에서 필요한 것들을 호출하는 형태로 작성이 가능하다.
public class TitleScene : BaseScene
{
protected override void Init()
{
base.Init();
SceneType = Define.Scenes.Title;
Managers.Player.Init();
Managers.Attack.Init();
Managers.Pool.Init();
Managers.UI.ShowSceneUI<UI_Title>();
}
}
이런식으로 말이다.
'스파르타 내배캠' 카테고리의 다른 글
스파르타 내배캠 Unity 3기 40일차 (0) | 2024.02.19 |
---|---|
스파르타 내배캠 Unity 3기 39일차 (0) | 2024.02.19 |
스파르타 내배캠 Unity 3기 37일차 (0) | 2024.02.14 |
스파르타 내배캠 Unity 3기 36일차 (0) | 2024.02.13 |
스파르타 내배캠 Unity 3기 35일차 (0) | 2024.02.09 |