싱글톤이란 디자인 패턴 중 하나로서 게임 상이나 메모리 상으로 단 하나만 존재하며
언제 어디서든 사용 가능한 오브젝트를 만들 때 사용되는 디자인 패턴입니다.
싱글톤의 특징 1. 👉 접근성
싱글톤의 특징 2. 👉 유일성
싱글톤의 특징 3. 👉 존속성
파일 매니저, 몬스터 매니저, 게임 매니저처럼 단 하나만 존재하는 오브젝트를 손쉽게 쓸 수 있는 필요가 있을때 사용합니다. 몬스터 오브젝터는 여러개지만 전체 몬스터를 관리해 줄 오브젝트는 “몬스터 매니저” 단 하나만 있으면 됩니다. 그럼 몬스터 매니저는 싱글톤을 사용하면 됩니다.
static Managers s_instance; // 1.
public static Managers Instance { get { init(); return s_instance; } } // 2.
static void init()
{
GameObject go = GameObject.Find("Managers"); // 3.
if (go == null)
{
go = new GameObject("Managers"); // 3-1.
go.AddComponent<Managers>(); // 3-2.
}
if (go.transform.parent != null && go.transform.root != null) // 4-1.
DontDestroyOnLoad(go.transform.root.gameObject); // 4-2.
else
DontDestroyOnLoad(go); // 4-3.
s_instance = go.GetComponent<Managers>(); // 5.
}
void Awake()
{
init(); // 6.
if (s_instance != this) // 7.
{
Destroy(gameObject.GetComponent<Managers>()); // 7-1,2.
}
}
🌍Managers
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Managers : MonoBehaviour
{
static Managers s_instance;
public static Managers Instance { get { init(); return s_instance; } }
static void init()
{
GameObject go = GameObject.Find("Managers");
if (go == null)
{
go = new GameObject("Managers");
go.AddComponent<Managers>();
}
if (go.transform.parent != null && go.transform.root != null)
DontDestroyOnLoad(go.transform.root.gameObject);
else
DontDestroyOnLoad(go);
s_instance = go.GetComponent<Managers>();
}
void Awake()
{
init();
if (s_instance != this)
{
Destroy(gameObject.GetComponent<Managers>());
}
}
}
🌍다른 클래스에서 사용(예시 : 플레이어에서 매니저사용)
public class Player : MonoBehaviour
{
void Start()
{
Managers mg = Managers.Instance;
//Managers.Instance.~~() //바로 접근도 가능
}
void Update()
{
}
}
하이얼아키에 Managers 오브젝트가 없는 경우
👇실행 전

👇실행 후 (Managers오브젝트를 만들고 스크립트 컴포넌트를 추가후 DontDestroyOnLoad에 포함)

빈 게임 오브젝트에 Managers 스크립트를 중복해서 넣은 경우
👇실행 전

👇실행 후(빈 게임 오브젝트에 있던 컴포넌트만 잘 삭제되었다.)



게임을 만들다보면 매니저 클래스가 많이 늘어나는데, 매번 이 설정을 하는게 번거로울 수 있습니다.
따라서 제네릭 클래스로 만들어 놓으면 필요할때 상속 받아서 간단하게 활용가능합니다.
🌍Singleton< T >
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
//상속 가능하도록 제네릭 클래스로 만들어준다.
//(where 조건 : 반드시 MonoBehaviour의 파생클래스 여야만 합니다.)
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
static T s_instance;
public static T Instance { get { init(); return s_instance; } }
static void init()
{
GameObject go = GameObject.Find(typeof(T).Name);
if (go == null)
{
go = new GameObject(typeof(T).Name);
go.AddComponent<T>();
}
if (go.transform.parent != null && go.transform.root != null)
DontDestroyOnLoad(go.transform.root.gameObject);
else
DontDestroyOnLoad(go);
s_instance = go.GetComponent<T>();
}
void Awake()
{
init();
if (s_instance != this)
{
Destroy(gameObject.GetComponent<T>());
}
}
}
🌍매니저로 만들 클래스에 상속
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager : Singleton<UIManager> //상속
{
void Start()
{
}
void Update()
{
}
public void Print()
{
//UI매니저에서 해야할 일
}
}
🌍다른 클래스에서 사용(예시 : 플레이어에서 UI매니저사용)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
void Start()
{
UIManager UM = UIManager.Instance;
UM.Print();
}
void Update()
{
}
}