강의, 책/[Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Section 8. Scene - Scene Manager

hye3193 2024. 1. 31. 16:18

Assets > Scripts > Utils > Define.cs에 씬과 관련된 열거체를 추가로 정의해준다

public enum Scene
{
    Unknown,
    Login,
    Lobby,
    Game
}

 

그리고 씬을 관리하기 위한 새로운 스크립트

Assets > Scripts > Scenes > BaseScene.cs를 생성해준다

public abstract class BaseScene : MonoBehaviour
{
    public Define.Scene SceneType { get; protected set; } = Define.Scene.Unknown;
    
    void Awake()
    {
        Init()
    }
    
    protected virtual void Init()
    {
        Object obj = GameObject.FindObjectOfType(typeof(EventSystem));
        if (obj == null)
            Managers.Resource.Instantiate("UI/EventSystem").name = "@EventSystem";
    }
    
    public abstract void Clear()
    {
    
    }
}

* Prefabs > UI 경로에 EventSystem 프리팹을 하나 만들어둬야 한다(그냥 씬에 있던 이벤트시스템 드래그 앤 드롭)

* Start 함수 대신 Awake 함수를 사용하게 되면, 컴포넌트를 꺼둔 상태에서도 Awake 함수가 동작한다

* 최상위 부모 Awake에 Init 함수를 넣어두면, 부모가 자식의 함수를 대신 실행해주기 때문에 좀 더 편리하게 작성이 가능하다(자식 클래스 내에서 Start나 Awake 함수에 Init을 넣지 않아도 됨)

 

그리고 Assets > Scripts > Scenes > GameScene.cs로 현재 게임 씬에 관련된 스크립트를 만들어준다

Hierarchy 창에서 @Scene이라는 이름의 비어 있는 게임 오브젝트를 만들어 준 뒤, 해당 스크립트를 부착시키면 된다

public class GameScene : BaseScene
{    
    protected override void Init()
    {
        base.Init();
        
        SceneType = Define.Scene.Game;
    }
    
    public override void Clear()
    {
    
    }
}

 

그리고 매니저를 만들어줄 건데, 유니티에서 이미 기본적으로 SceneManager를 지원하므로

Assets > Scripts > Managers > SceneManagerEx.cs 라는 이름(ex: extend)으로 만들어준다

public class SceneManagerEx
{
    public BaseScene CurrentScene { get { return GameObject.FindObjectOfType<BaseScene>(); } }

    public void LoadScene(Define.Scene type)
    {
        CurrentScene.Clear();
        SceneManager.LoadScene(GetSceneName(type));
    }
    
    string GetSceneName(Define.Scene type)
    {
        string name = System.Enum.GetName(typeof(Define.Scene), type);
        return name;
    }
}

 

그리고 Manager 스크립트에 아래와 같이 연결해준다

SceneManagerEx _scene = new SceneManagerEx();

public static SceneManagerEx Scene { get { return Instance._scene; } }

 

Managers.Scene.LoadScene(Define.Scene.Game);

그리고 위와 같이 사용해주면 Define에서 정의된 Scene 중 game을 가져와서 로드시킬 수 있다