싱글톤(Singleton)
- 전 환경을 통틀어 유일무이한 객체를 만들기 위한 디자인 패턴
- 하나의 클래스에 단 하나의 인스턴스만 존재하게 한다.
- 단 하나만 있어야 하는 오디오 매니저, 게임 매니저 등에 사용된다.
- 보통 제네릭 타입으로 만들어 놓고 상속받는다.
싱글톤을 구현하기 위해서는 우선 static으로 인스턴스를 선언해 주는 것이 중요하다.
그리고 그 인스턴스를 자기 자신이 참조하고, 두 개 이상 생성되지 못하게 막는 것이 싱글톤의 원리이다.
간단한 싱글톤의 예시를 보자면 ,
using UnityEngine;
public class SimpleSingleton : MonoBehaviour
{
public static SimpleSingleton Instance;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(gameObject);
}
}
}
다음과 같다, 만일 인스턴스가 존재하지 않는다면 자기 자신을 참조하고,
존재한다면 생성된 게임오브젝트를 지워버린다.
그래서 결국엔 인스턴스를 갖고 있는 객체는 하나만 존재하게 된다.
다음은 약간 발전된 형태의 싱글톤이다.
만일 Awake 전에 어디에선가 싱글톤을 참조하려고 하면, 위의 경우는 오류가 날 수 있기에 고안된 방법이다.
(그러나 Awake 전에 참조하지 않게 하는 것을 목표로 해야한다)
public class Singleton : MonoBehaviour
{
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
{
SetupInstance();
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(gameObject);
}
}
private static void SetupInstance()
{
instance = FindObjectOfType<Singleton>();
if (instance == null)
{
GameObject gameObj = new GameObject();
gameObj.name = "Singleton";
instance = gameObj.AddComponent<Singleton>();
DontDestroyOnLoad(gameObj);
}
}
null 검사를 2번 해서 인스턴스가 없다면 새로운 게임 오브젝트를 만들고, 그 안에 이 싱글톤 클래스를 만들어 집어넣고
인스턴스에 할당해준다. 그 후 씬이 바뀌어도 파괴되지 않게 한다.
이런 방식으로 싱글톤을 제작한다면, 싱글톤으로 만들고자 하는 것의 타입이 바뀔 때마다 새로운 싱글톤을 만들어 사용해야 한다. 예를 들 BGM 매니저를 싱글톤으로 만들고자 한다면 다음과 같이 작성해야 한다.
public class BGMManager : MonoBehaviour
{
private static BGMManager instance;
public static BGMManager Instance
{
get
{
if (instance == null)
{
GameObject obj = new GameObject("BGMManager");
instance = obj.AddComponent<BGMManager>();
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject); // 씬 변경 시 파괴되지 않음
}
else
{
Destroy(gameObject); // 중복 생성 방지
}
}
public void PlayMusic()
{
Debug.Log("배경 음악 재생!");
}
public void StopMusic()
{
Debug.Log("배경 음악 중지!");
}
}
만일 이 경우 또 GameManager를 추가하고자 하면 비슷한 과정을 반복해야 한다.
이런 반복을 방지하기 위해 제네릭 타입으로 싱글톤을 만들고 상속을 통해 번거로움을 해결한다.
public class Singleton<T> : MonoBehaviour where T : Component
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
SetupInstance();
}
}
return instance;
}
}
public virtual void Awake()
{
RemoveDuplicates();
}
private static void SetupInstance()
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
GameObject gameObj = new GameObject();
gameObj.name = typeof(T).Name;
instance = gameObj.AddComponent<T>();
DontDestroyOnLoad(gameObj);
}
}
private void RemoveDuplicates()
{
if (instance == null)
{
instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
이런 식으로 제네릭 타입으로 싱글톤을 만들고,
public class GameManager: Singleton<GameManager>
{
// ...
}
싱글톤을 상속시켜 다른 싱글톤이 필요한 클래스들을 간편하게 관리할 수 있다.
주의해야 할 점은, Awake에서 싱글톤에 필요한 RemoveDuplicates() 함수를 만들어 인스턴스에 객체를 할당해 주고 있으므로, 자식 클래스들에서 Awake를 쓸 때에는 주의를 해 주어야 한다. 혹은 Awake안에 OnAwake를 호출하고 자식 클래스에서 OnAwake를 구현하는 방식으로도 사용할 수 있다.
내 첫 디자인 패턴 공부 끝 !
참조한 자료
https://unity.com/kr/resources/design-patterns-solid-ebook
디자인 패턴 및 SOLID 원칙으로 코딩 스킬 업그레이드 | Unity
11가지 프로그래밍 패턴에 대한 가이드를 통해 Unity 프로젝트를 개선해 보세요. 샘플 프로젝트를 다운로드하고 코딩 스킬을 업드레이드해 보세요.
unity.com
난 지금까지 한글 버전이 없는줄 알았는데...ㅎ..ㅎ.ㅎ.ㅎ.ㅎ..ㅎ.
https://www.youtube.com/watch?v=Tf_VZEgnag0&t=577s
https://www.youtube.com/watch?v=-wzULWMvFu0&t=6s
https://www.youtube.com/watch?v=zvOVk2e01go&t=1021s
https://chatgpt.com/share/6774fef9-c53c-800d-b153-4ed3e49aac79
ChatGPT - 싱글톤 패턴 설명
Shared via ChatGPT
chatgpt.com
싱글톤과 싸움한 기록.
'개념공부' 카테고리의 다른 글
델리게이트, 람다, Action,Func (0) | 2025.01.07 |
---|---|
Factory Pattern with Unity (0) | 2025.01.01 |
About UI ( with Unity) (1) | 2024.12.27 |
Unity에서 Sound의 기본 개념 (2) | 2024.12.24 |
Unity Camera (0) | 2024.12.23 |