갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • c# 코루틴
  • C# 예외 처리
  • C++ 상속
  • C++
  • 유니티 그래프
  • C# boxing
  • 전세계게임매출순위
  • 2020년 게임 매출
  • 글로벌게임매출
  • 게임매출순위
  • 유니티 골드그래프
  • c# Thread
  • 자바
  • c# coroutine
  • 게임 매출 순위
  • C++ 소멸자
  • 알고리즘
  • c# collection
  • 전세계 게임 매출
  • 강남 방탈출
  • c# unboxing
  • 모바일 게임 순위
  • c# delegate
  • pc게임 순위
  • Unity Graph
  • 게임 디자인 패턴
  • 유니티 그래프 그리기
  • pc 게임 순위
  • 롤 골드그래프
  • C++ virtual

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[유니티] MonoSingleton
프로그래밍/유니티

[유니티] MonoSingleton

2022. 1. 14. 02:35
728x90
반응형

 

유니티에서 싱글톤을 쓰면서 MonoBehaviour를 상속받는 싱글톤과 아닌것을 나누는 필요성을 느꼈다.

 

만들고나니 왠만한 프로젝트에서 다 써도 될 것 같아 남김

 

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

//씬 변경시 삭제가 되야하는 싱글톤들은 'class : MonoSingleton<T>, IDestructible' 의 형태로 선언한다.
interface IDestructible
{
}
//하이라키에서 보여져야 하는 싱글톤들은 'class : MonoSingleton<T>, IAppearable' 의 형태로 선언한다.
interface IAppearable
{
}

//싱글톤 관리 루트 클래스
public static class SingletonRoot
{
    public const string SingletonRootName = "ManagerRoot";
    
    private static GameObject _singletonRootInstance = null;

    public static GameObject GetRootInstance()
    {
        if (_singletonRootInstance == null && Application.isPlaying)
        {
            _singletonRootInstance = new GameObject(SingletonRootName);
            _singletonRootInstance.AddComponent<RectTransform>();
            GameObject.DontDestroyOnLoad(_singletonRootInstance);
        }

        return _singletonRootInstance;
    }

    public static GameObject EditGetRootInstance()
    {
        if (_singletonRootInstance == null)
        {
            _singletonRootInstance = new GameObject(SingletonRootName);
        }

        return _singletonRootInstance;
    }

    public static void DestroyInstance()
    {
        GameObject.DestroyImmediate(_singletonRootInstance);
    }
}

//매니저 클래스의 부모가 되는 MonoBehaviour 타입의 싱글턴 클래스
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    public const string StaticManagerOption = "(Static)";
    public const string DynamicManagerOption = "(Dynamic)";

    protected static T _instance = null;

    public static bool IsNull()
    {
        return _instance == null;
    }

    public static T Instance 
    { 
        get 
        { 
            if(_instance == null)
            {
                _instance = FindObjectOfType<T>();
                if(_instance == null)
                {
                    CreateInstance();
                }
                else
                {
                    SetInstanceObject(_instance.gameObject);
                }
            }
            return _instance; 
        } 
    }

    public static void CreateInstance()
    {
        if (_instance != null || Application.isPlaying == false)
            return;
                
        GameObject singletonObject = new GameObject(typeof(T).ToString());
        _instance = singletonObject.AddComponent<T>();

        if(_instance is IAppearable)
        {
            singletonObject.hideFlags = HideFlags.None;
        }
        else
        {
            singletonObject.hideFlags = HideFlags.HideInHierarchy;
        }

        SetInstanceObject(singletonObject);
    }

    private static void SetInstanceObject(GameObject singletonObject)
    {
        //인터페이스 클래스의 유무 따라 옵션형태로 기능이 추가된다.
        if (_instance is IDestructible == false)
        {
#if UNITY_EDITOR
            singletonObject.name = singletonObject.name + StaticManagerOption;
#endif
            if (Application.isPlaying)
                DontDestroyOnLoad(singletonObject);

            singletonObject.transform.parent = SingletonRoot.GetRootInstance().transform;
        }
        else
        {
#if UNITY_EDITOR
            singletonObject.name = singletonObject.name + DynamicManagerOption;
#endif
        }
    }
    
    public static void DestroyInstance()
    {
        if (_instance == null)
            return;

        Destroy(_instance.gameObject);
        _instance = null;
    }

    public virtual void OnDestroy()
    {
        //인터페이스 클래스의 유무 따라 옵션형태로 기능이 추가된다.
        if (_instance is IDestructible || Application.isPlaying == false)
        {
            DestroyInstance();
        }
    }

    public static void EditCreateInstance()
    {
        if (_instance != null)
            return;
        
        GameObject singletonObject = new GameObject(typeof(T).ToString());
        _instance = singletonObject.AddComponent<T>();

        if (_instance is IAppearable)
        {
            singletonObject.hideFlags = HideFlags.None;
        }
        else
        {
            singletonObject.hideFlags = HideFlags.HideInHierarchy;
        }

        EditSetInstanceObject(singletonObject);
    }

    private static void EditSetInstanceObject(GameObject singletonObject)
    {
        //인터페이스 클래스의 유무 따라 옵션형태로 기능이 추가된다.
        if (_instance is IDestructible == false)
        {
            singletonObject.name = singletonObject.name + StaticManagerOption;
            if (Application.isPlaying)
                DontDestroyOnLoad(singletonObject);

            singletonObject.transform.parent = SingletonRoot.EditGetRootInstance().transform;
        }
        else
        {
            singletonObject.name = singletonObject.name + DynamicManagerOption;
        }
    }
}
728x90
반응형

'프로그래밍 > 유니티' 카테고리의 다른 글

[유니티] 터치 이펙트 (Click Particle)  (0) 2022.07.12
[유니티] Hierarchy의 오브젝트 Path복사  (0) 2022.03.09
[유니티] 롤 골드그래프를 만들어보자(4) - 최종 코드  (0) 2021.08.12
[유니티] 롤 골드그래프를 만들어보자(3) - 그래프 내부 채우기  (2) 2021.08.12
[유니티] 롤 골드그래프를 만들어보자(2) - 선 찍기  (0) 2021.08.10
    '프로그래밍/유니티' 카테고리의 다른 글
    • [유니티] 터치 이펙트 (Click Particle)
    • [유니티] Hierarchy의 오브젝트 Path복사
    • [유니티] 롤 골드그래프를 만들어보자(4) - 최종 코드
    • [유니티] 롤 골드그래프를 만들어보자(3) - 그래프 내부 채우기
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바