GameDevelop/Unity기초쌓기

Unity 싱글톤(Singleton) 패턴

도도돋치 2025. 5. 1. 21:22
Contents 접기
728x90

게임을 만들다 보면 "어디서든 접근 가능한 하나뿐인 객체" 가 필요할 때가 많다.

 

나도 개발하면서 GameManager, SoundManager, UIManager 같은 걸 만들어야 했다.

그럴 때 쓸수 있는 것이 바로 싱글톤(Singleton) 패턴이다.

 

싱글톤이란?

싱글톤: 프로그램에서 단 하나의 인스턴스만 존재하도록 보장하는 디자인 패턴.

 

쉽게 말하면

  • 전역 변수처럼 접근 가능
  • 무조건 하나만 존재해야 함

 

Unity에서 싱글톤 구현 방법

Unity에서 싱글톤은 보통 2가지 방식으로 만든다:

  1. 일반 클래스 싱글톤
  2. MonoBehaviour 싱글톤

 

1. 일반 클래스 싱글톤

MonoBehaviour를 상속받지 않는 경우

public class GameManager
{
    private static GameManager _instance;
    public static GameManager Instance
    {
        get
        {
            if (_instance == null)
                _instance = new GameManager();
            return _instance;
        }
    }

    // 외부에서 new GameManager() 호출 못 하게 private 생성자
    protected GameManager() { }

    public void InitGame()
    {
        // 초기화 코드
    }
}

 

중요 포인트

  • Instance를 통해서만 객체를 만들 수 있다.
  • protected 생성자 덕분에 상속이 가능하다.

 

2. MonoBehaviour 싱글톤

Unity 컴포넌트로 만들어야 할 때

using UnityEngine;

public class GameManager : MonoBehaviour
{
    private static GameManager _instance;
    public static GameManager Instance
    {
        get
        {
            if (_instance == null)
            {
                // 씬에 존재하는지 찾아본다
                _instance = FindObjectOfType<GameManager>();
                if (_instance == null)
                {
                    // 없다면 새로 생성
                    GameObject go = new GameObject("GameManager");
                    _instance = go.AddComponent<GameManager>();
                }
            }
            return _instance;
        }
    }

    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject); // 씬 이동 시 파괴 방지
        }
        else
        {
            Destroy(gameObject); // 중복 생성을 막음
        }
    }

    public void InitGame()
    {
        // 초기화 코드
    }
}

 

✅ MonoBehaviour 싱글톤 특징

  • Unity 컴포넌트 기능 (Start(), Update()) 사용 가능
  • 씬 이동해도 파괴되지 않게 DontDestroyOnLoad()
  • 대신, 상속이 까다롭다
    • Awake()를 protected virtual로 열어두면 상속 후 override 가능!

 

싱들톤 장단점

[1] 싱글톤 쓸 때 좋은 경우

  • 게임 전역 관리 (GameManager, AudioManager, UIManager)
  • 씬 이동 시에도 살아있어야 하는 매니저
  • 저장된 데이터 관리 (PlayerData, SettingManager)

[2] 싱글톤 쓸 때 주의할 점

  • 남용하면 전역 변수 남발이 된다.
  • 테스트하기 어렵다 (Mocking 힘듦)
  • 메모리 누수 주의 (특히 DontDestroyOnLoad() 많이 쓰면)
  • 씬에 미리 넣어둔 오브젝트와 충돌 주의 (FindObjectOfType)

 

정리

  • 일반 클래스 싱글톤: 상속 가능, Unity 기능 X
  • MonoBehaviour 싱글톤: Unity 기능 O, 상속 시 Awake() 조심
  • 필요할 때 꼭 하나만 만들어야 할 때 써야 한다.

 

728x90