본문 바로가기
1일 1 구현

[1일 1 구현] Managers.cs

by LemongO 2024. 6. 4.

Managers - 모든 매니저를 총괄하는 GameObject

 

본격적인 구현에 앞서 각종 매니저들의 싱글톤 구현 코드가 너무 날 것이고 하이어라키에 여러개의 매니저가 올라와 있는게 보기가 싫었다.

그래서 하나의 GameObject에 모든 Manager를 담는 방식으로 구현한다. - Rookiss 참고.

 

구현 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Managers : MonoBehaviour
{
    static Managers s_instance;
    static Managers Instance { get { Init(); return s_instance; } }

    #region Core
    ResourceManager _resource = new ResourceManager();
    PoolManager _pool = new PoolManager();
    UIManager _ui = new UIManager();

    public static ResourceManager RM => Instance?._resource;
    public static PoolManager Pool => Instance?._pool;
    public static UIManager UI => Instance?._ui;
    #endregion

    static void Init()
    {
        if(s_instance == null)
        {
            GameObject go = GameObject.Find("@Managers");

            if(go == null)
            {
                go = new GameObject("@Managers");
                go.AddComponent<Managers>();
            }

            DontDestroyOnLoad(go);
            s_instance = go.GetComponent<Managers>();
        }
    }
}

 

이전에 유튜브나 다른 글에서 배웠던 것으론 대체로 Manager.Instance. <<< 이렇게 접근을 했다.

여기서도 적용을 하려면 Managers.Instance.Pool. 이런식으로 접근을 해야하는데 이러면 너무 길어지니 줄이기 위해

 

Instance는 외부에서 접근하지 못하도록 private으로 선언.

대신 각종 매니저를 public static으로 선언 후 Instance가 있으면, 즉 싱글톤이 존재하면 Managers 싱글톤의 해당 매니저를 반환하도록 만들었다.

 

기본적으로 Monobehaviour는 new 키워드를 사용할 수 없으니 Monobehaviour 상속을 없애고 일반 클래스로 만들어

Managers 클래스에서 생성, 모두 관리하도록 설계했다.

그리고 Init 메서드를 통해 씬에 Managers 싱글톤이 존재하지 않다면 바로 싱글톤을 만드는 방식을 사용.

DontDestroy 메서드로 제거하기 전까진 계속 들고간다.

 

단, 이렇게 했을 때 명백한 단점이 몇가지 존재한다.

 

  1. 각 매니저의 Delegate에 구독된 메서드가 있다면 씬 전환 시 반드시 구독해제를 시켜야 한다.
  2. 각 매니저는 코루틴 사용이 불가능하다.
  3. 몇몇 매니저를 특정 씬에선 사용하지 않더라고 계속 들고있다.

1번은 프로젝트를 만들면서 계속해서 신경써야하는 부분이다.

3번은 설계상 어쩔 수 없는 부분이지만 그렇게 성능상으로 무리가 가진 않을 것으로 보인다.

 

2번은 코루틴을 대신 호출해줄 CoroutineManager를 별도로 만들어 해결할 수 있다.


CoroutineManager

using System.Collections;
using UnityEngine;

public class CoroutineManager : MonoBehaviour
{
    private static CoroutineManager monoInstance;

    [RuntimeInitializeOnLoadMethod]
    private static void Initialize()
    {        
        monoInstance = new GameObject("[CoroutineManager]").AddComponent<CoroutineManager>();
        DontDestroyOnLoad(monoInstance.gameObject);        
    }

    public static Coroutine StartCoroutineEx(IEnumerator coroutine)
    {
        return monoInstance.StartCoroutine(coroutine);
    }

    public static void StopCoroutineEx(Coroutine coroutine)
    {
        monoInstance.StopCoroutine(coroutine);
    }
}

 

  • RuntimeInitializeOnLoadMethod 어트리뷰트를 사용해 프로그램이 실행될 때 호출이 되도록 만들어
    런타임 동안 사용할 CoroutineManager 오브젝트를 생성 및 DontDestroy 한다.
  • StartCoroutine의 경우 IEnumerator를, StopCoroutine의 경우 Coroutine을 매개변수로 받아 대신 호출한다.

 

'1일 1 구현' 카테고리의 다른 글

[1일 1 구현] PoolManager - 2  (0) 2024.05.18
[1일 1 구현] PoolManager - 1  (0) 2024.05.16
[1일 1 구현] 코드 정리 및 공통 클래스  (0) 2024.05.15
[1일 1 구현] UI Base  (0) 2024.05.13
[1일 1 구현] UI Manager  (0) 2024.05.13