Unity/Study

유니티 Manager System

홍삼맛 2023. 12. 5. 20:19

기능 소개

  • 플레이어 정보를 관리하기 위해 Manager System 구축
  • Managers를 통해 각 담당 매니저를 인스턴스 하는 클래스 구현 [제너릭 싱글톤]

기능 구현

제너릭 싱글톤

public abstract class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T>
{
    private static T instance = null;
    public static T Instance { get { return instance; } }

    protected virtual void Awake()
    {
        if (instance != null)
        {
            Debug.LogError(string.Format("허용되지 않은 중복 인스턴스 => {0}", typeof(T)));
            Destroy(this);
            return;
        }

        instance = (T)this;
    }

    protected virtual void OnDestroy()
    {
        if (instance == this)
        {
            instance = null;
        }
    }
}
  • 제네릭 싱글톤을 만들어 각 클래스마다 인스턴스를 만들 필요 없이 데이터 형식으로 상속받을 수 있게 만든다
  • 추가적으로 MonoBehaviour의 기능도 가져온다

Managers

public class Managers : SingletonBehaviour<Managers>
{
    private readonly ResourceManager resource = new();
    private readonly UIManager ui = new();
    private readonly GameManager game = new();

    public static ResourceManager Resource => Instance != null ? Instance.resource : null;
    public static UIManager UI => Instance != null ? Instance.ui : null;
    public static GameManager Game => Instance != null ? Instance.game : null;
}
  • 제네릭 싱글톤으로 Managers를 초기화하고, 일반 클래스로 각 담당 Manager들을 생성하고 인스턴스 해준다

ResourceManager

public class ResourceManager
{
    private Dictionary<string, GameObject> prefabs = new();

    public void Initialize()
    {
        // 오브젝트 프리팹
        GameObject[] objs = Resources.LoadAll<GameObject>("Prefabs");
        foreach (GameObject obj in objs) prefabs[obj.name] = obj;
    }

    /// <summary>
    /// 리소스 폴더 내에 프리팹 생성
    /// </summary>
    /// <param name="prefabName">해당 프리팹 이름</param>
    public GameObject Instantiate(string prefabName)
    {
        if (!prefabs.TryGetValue(prefabName, out GameObject prefab)) return null;
        return GameObject.Instantiate(prefab);
    }
}
  • 리소스 관련 파일은 Resources 폴더 내에 관리하여, Dictionary로 저장하거나 List 또는 배열로 값을 호출한다

GameManager

public class GameManager
{
    public MainScene Main { get; private set; }
    public MainSceneUI MainUI { get; private set; }
    public GameState State { get; set; }
    public StageBlueprint[] Stages { get; private set; }
    public int CurrentLevel { get; set; }
    public int Bricks { get; set; }
    public int Life { get; set; }

    /// <summary>
    /// Managers Awake 초기화
    /// </summary>
    public void Initialize()
    {
        Stages = Managers.Resource.GetStages();
    }
    
    /// <summary>
    /// 메인 씬 OnStart 초기화
    /// </summary>
    public void InitScene()
    {
        Main = Object.FindObjectOfType<MainScene>();
        MainUI = Object.FindObjectOfType<MainSceneUI>();

        State = GameState.Play;
        Bricks = Stages[CurrentLevel].Bricks;
    }
}
  • 게임을 구성하는 씬과 UI를 FindObjectType으로 찾고, 게임 기본 로직을 초기화한다