내일배움캠프 Unity 9기/TIL
[Unity/TIL] - 싱글톤
song-ssi
2025. 6. 10. 12:22
1. 싱글톤. 왜 쓰나요?
특정 클래스가 게임 전체에서 단 하나만 존재하도록 보장하고,
전역 접근이 가능하도록 만들기 위해.
대표적으로 GameManager, SoundManager, UIController 등에 사용.
2. 기본 싱글톤 패턴
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
private void Awake()
{
// 인스턴스가 이미 존재하면 이 오브젝트는 제거
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
// 인스턴스 설정 및 씬 이동 시에도 유지
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
3. 사용 방법
GameManager.Instance.YourFunction();
4. 유의 사항
- Awake() 안에서 인스턴스 중복 체크 꼭 해줘야 함.
- DontDestroyOnLoad()를 쓰면 씬이 바뀌어도 오브젝트가 유지됨.
- Instance에 직접 접근할 수 있도록 public static으로 선언.
- Instance는 private set으로 외부에서 변경 불가능하게 막는 게 안전.
✅ UIManager 싱글톤 예제
using System.Collections.Generic;
using UnityEngine;
public class UIManager : MonoBehaviour
{
public static UIManager Instance { get; private set; }
[SerializeField] private List<GameObject> uiList; // Inspector에 등록
private Dictionary<string, GameObject> uiDict = new Dictionary<string, GameObject>();
private void Awake()
{
// 싱글톤 패턴
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
// Dictionary로 등록
foreach (GameObject ui in uiList)
{
if (ui != null)
uiDict[ui.name] = ui;
}
}
/// <summary>
/// 특정 UI 창 열기
/// </summary>
public void OpenUI(string uiName)
{
if (uiDict.TryGetValue(uiName, out GameObject ui))
{
ui.SetActive(true);
}
else
{
Debug.LogWarning($"❗ UIManager: {uiName} UI를 찾을 수 없음");
}
}
/// <summary>
/// 특정 UI 창 닫기
/// </summary>
public void CloseUI(string uiName)
{
if (uiDict.TryGetValue(uiName, out GameObject ui))
{
ui.SetActive(false);
}
}
/// <summary>
/// 전체 UI 닫기
/// </summary>
public void CloseAllUI()
{
foreach (var ui in uiDict.Values)
{
ui.SetActive(false);
}
}
}
✅ 사용법 예시
// UI 열기
UIManager.Instance.OpenUI("Inventory");
// UI 닫기
UIManager.Instance.CloseUI("Crafting");
// 전체 UI 닫기
UIManager.Instance.CloseAllUI();
✅ UI 오브젝트 등록 팁
- UI 오브젝트는 Canvas 아래에 배치하고, uiList 리스트에 Inspector에서 등록하기.
- 각각의 UI GameObject는 이름(gameObject.name)을 고유하게 설정해두기. (예: "Inventory", "Crafting" 등).