Unity/이론

Singleton Pattern (Unity)

QuickClid 2024. 5. 12. 13:16

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;
        }
    }
}

읽어주셔서 감사합니다!

궁금한 점이 있다면 댓글로 문의주세요!