Deff_Dev

[Unity/C#] Generic Singleton (제네릭 싱글톤) 본문

Unity(유니티)/유니티 공부

[Unity/C#] Generic Singleton (제네릭 싱글톤)

Deff_a 2024. 5. 28. 22:30

 

게임 개발 할 때, 가장 많이 사용하는 디자인 패턴 중 하나인 싱글톤 패턴을 사용한다고 하면

    public static GameManager _Intstance;

    private void Awake()
    {
        _Intstance = this;
    }

 

이런식으로 많이 사용했을 것 이다.

 

예외 처리, 프로퍼티,DontDestroyOnLoad 설정 등을 포함한 다양한 기능을 구현할 때,  싱글톤으로 선언된 클래스가 많아진다면 긴 코드를 각각의 싱글톤으로 선언한 클래스마다 작성해줘야한다.

 

이 과정은 중복된 코드를 많이 생성하게 되고 유지 보수적인 측면에서도 좋지않다.

(하나의 기능을 추가/삭제할 때 싱글톤으로 선언된 모든 클래스를 다 수정해야한다.)

 

Generic Class를 이용해 이 문제를 해결할 수 있다.


using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if(instance == null)
            {
                // 해당 컴포넌트를 가지고 있는 게임 오브젝트를 찾아서 반환한다.
                instance = (T)FindAnyObjectByType(typeof(T));

                if (instance == null) // 인스턴스를 찾지 못한 경우
                {
                    // 새로운 게임 오브젝트를 생성하여 해당 컴포넌트를 추가한다.
                    GameObject obj = new GameObject(typeof(T).Name, typeof(T));
                    // 생성된 게임 오브젝트에서 해당 컴포넌트를 instance에 저장한다.
                    instance = obj.GetComponent<T>();
                }
            }

            return instance;
        }
    }

    private void Awake()
    {
        if(transform.parent != null && transform.root != null) // 해당 오브젝트가 자식 오브젝트라면
        {
            DontDestroyOnLoad(this.transform.root.gameObject); // 부모 오브젝트를 DontDestroyOnLoad 처리
        }
        else
        {
            DontDestroyOnLoad(this.gameObject); // 해당 오브젝트가 최 상위 오브젝트라면 자신을 DontDestroyOnLoad 처리
        }
    }
}
using UnityEngine;

public class GameManager : Singleton<GameManager>
{

}

 

싱글톤으로 선언할 클래스에서 Singleton 클래스를 상속받게 된다면 싱글톤 선언이 완료된다.

 

해당 방법을 사용하면 코드의 가독성과 유지보수성을 상승시킬 수 있어 싱글톤 패턴을 여러 클래스에서 사용할 경우 Generic Singleton을 사용하면 좋을 것 같다.