728x90
싱글톤
싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 어디에서든 그 인스턴스에 접근할 수 있도록
보장하는 디자인 패턴이다.
- 클래스가 자신의 인스턴스 하나만 인스턴스화할 수 있도록 보장
- 여러개를 만들어도 하나만 남음
- 해당 단일 인스턴스에 대한 손쉬운 전역 엑세스를 제공
- 하나의 객체만 존재할 필요가 있을 때
- 상태창
- 게임 매니저
- 오디오 매니저
- 파일 관리자
- UI Settings
- 등등
- 안티 패턴으로 취급되기도 함
- 양날의 검
- 커플링 발생하기 쉬운 구조
- 멀티스레드 환경에서는 동기화 처리가 필요
- 테스트 및 디버깅이 불편
- 생성 시점이 명확하지 않음
=> 필요한 경우에만 주의해서 사용해야 한다.
싱글톤 코드
using UnityEngine;
public class SimpleSingleton:MonoBehaviour{
public static SimpleSingleton instance;
private void Awake(){
if(instance == null){
instance = this;
}
else{
Destroy(gameObject);
}
}
}
//새 Scene을 부르면 GameObject가 지워짐
//사용되기 전에 하이어라키에서 셋업 되어야함
자기 자신의 인스턴스를 static으로 가지고 있다.
클래스에서 static으로 선언되면 여러 인스턴스가 있더라도 메모리 공간을 하나만 차지하게된다.
MonoBehaviour을 사용하지 않는 경우(씬에 올리지 않는 경우)
using UnityEngine;
public class SimpleSingleton{//MonoBehaviour을 안쓰는 경우
public static SimpleSingleton Instance;
public static SimpleSingleton Instance{
get{
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
}
멀티 쓰레드 환경에서는 문제가 될 수 있다.
쓰레드 세이프 X
⬇️ 개선 코드 ⬇️
public class SimpleSingleton{
private static bolatile SipleSingleton instance = null;
private static readonly object padlock = new object();
...
public static SimpleSingleton Instance{
get{
if(instance ==null){
lock(padlock){
if(instance == null){
instance = new SimpleSingleton();
}
}
}
return instance;
}
}
}
//또는
public sealed class SinpleSingleton{
private static readonly SimpleSingleton instance = new SimpleSingleton();
//Private constructor ensures that an object is not instantiated from outside the class
private SinpleSingleton(){
}
//Public static property to get the single instance of the class
public static SimpleSingleton Instance{
get{
return instance;
}
}
}
다른 씬을 불러와도 삭제되지 않도록 개선된 코드
using UnityEngine;
public class Singleton:MonoBehaviour{
public static Singleton instance;
public static Singleton Instance{
get{
if(instance==null){
SetupInstance();
}
return instacne;
}
}
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);
}
}
싱글톤이 여러개 있는 경우
public calss 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 GameObj();
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>{
//...
}
728x90
'공부 > Unity & C#' 카테고리의 다른 글
[Visual Studio] 클래스 다이어그램 보기 (0) | 2025.04.07 |
---|---|
[Unity] 옵저버 패턴(Observer Pattern) (0) | 2025.04.01 |
[Unity 2D]시네머신 카메라로 카메라 범위 제한하기 (0) | 2025.03.26 |
[멋쟁이사자처럼부트캠프 Unity 게임개발 4기] 시네머신 카메라로 카메라 범위 조정하기 (0) | 2025.03.18 |
[Unity] Object.Instantiate (0) | 2024.01.31 |