Singleton Pattern이란?
하나의 Scene에 "반드시" 하나의 Object만 존재하도록 강제하는 디자인 패턴이다.
사용처
주로 Manager 계열의 Object에 사용된다.
이유 : 대부분의 경우 이러한 Object는 모든 Scene에 사용된다. 그러나 매번 넣어주기도 귀찮고, 실수할 가능성도 있다. 또한 Scene Template을 사용하더라도, 무조건 사용되는 Object들이 매번 Hierarchy 창을 차지한다면, 각각의 Scene을 편집하는 데 있어 상당한 방해가 된다.
사용법
대체로 Main Menu와 같은, "무조건 맞닥뜨리게 되는(=index가 0인 Scene)"에 Game, Data, Audio Manager Object를 배치한다. 그 후, 그것들을 DontDestroyOnLoad 목록에 등록하여 재사용한다.
Skeleton Code - Game Manager
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameObject game_manager;
private void Awake()
{
SingletonCheck();
}
private void SingletonCheck()
{
if (game_manager == null)
{
game_manager = gameObject;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
// 처음 로드됐을 시에만 "단 한 번" 실행하고 싶은 것들을 여기에.
}
}
문제점
DontDestroyOnLoad를 사용하기 때문에, Start()가 단 한 번밖에 실행되지 않는다. (그러니까, Main Menu Scene을 10번 Load하더라도 Game Manager의 Start()는 단 한 번만 호출된다!) 따라서 "Scene이 Load되는 타이밍"에 "매번" 실행하고 싶은 메서드가 있다면, Delegate를 사용해야 한다.
해결책
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameObject game_manager;
private void Awake()
{
SingletonCheck();
}
private void SingletonCheck()
{
if (game_manager == null)
{
game_manager = gameObject;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.name == "Main Menu")
{
// Main Menu Scene이 Load됐을 때만 하고 싶은 것을 적으면 됨.
return;
}
if (scene.name == "Shop")
{
// Shop Scene이 Load됐을 때만 하고 싶은 것을 적으면 됨. 등등...
return;
}
}
}