Unity/디자인 패턴

[Unity] 디자인 패턴 - 싱글톤(Singleton) 패턴 이해하기

MayQ 2025. 6. 3. 21:46

개요

안녕하세요! 오늘은 유니티(Unity)에서 싱글톤(Singleton) 디자인 패턴을 어떻게 사용하는지에 대해 자세히 알아보겠습니다. 싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 그 인스턴스에 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다. 이는 게임 개발에서 매우 유용하게 사용됩니다.

싱글톤 디자인 패턴이란?

싱글톤 디자인 패턴은 객체를 하나만 생성하고, 그 객체를 어디서든지 참조할 수 있도록 보장하는 패턴입니다. 이를 통해 글로벌 상태를 관리하거나, 자원을 효율적으로 사용하며, 여러 객체 간의 데이터 공유를 쉽게 할 수 있습니다.

싱글톤 패턴의 필요성

  1. 글로벌 상태 관리: 게임의 점수, 설정, 게임 관리 객체 등 전역적으로 관리해야 할 데이터를 싱글톤으로 관리할 수 있습니다.
  2. 자원 절약: 동일한 객체를 여러 번 생성하지 않기 때문에 메모리와 자원을 절약할 수 있습니다.
  3. 코드 구조의 간소화: 전역 변수를 사용하지 않고도 전역적으로 접근 가능한 객체를 만들 수 있어 코드의 구조를 간소화할 수 있습니다.

유니티에서 싱글톤 패턴 구현하기

Step 1: 기본 싱글톤 클래스 만들기

유니티에서 싱글톤 패턴을 구현하기 위해서는 기본적으로 다음과 같은 구조를 따릅니다.

using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    // 클래스의 유일한 인스턴스를 저장하는 정적 변수
    private static T _instance;

    // 외부에서 싱글톤 인스턴스에 접근할 수 있도록 하는 정적 프로퍼티
    public static T Instance
    {
        get
        {
            // 인스턴스가 아직 생성되지 않았다면
            if (_instance == null)
            {
                // 씬에서 해당 타입의 객체를 찾아 할당
                _instance = (T)FindObjectOfType(typeof(T));

                // 만약 씬에 해당 타입의 객체가 없다면 새로 생성
                if (_instance == null)
                {
                    GameObject singletonObject = new GameObject();
                    _instance = singletonObject.AddComponent<T>();
                    singletonObject.name = typeof(T).ToString() + " (Singleton)";
                }
            }

            return _instance;
        }
    }

    // 싱글톤 인스턴스가 중복 생성되지 않도록 하는 메서드
    protected virtual void Awake()
    {
        // 인스턴스가 아직 존재하지 않으면 현재 인스턴스를 할당하고 파괴되지 않도록 설정
        if (_instance == null)
        {
            _instance = this as T;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            // 이미 인스턴스가 존재하면 현재 게임 객체를 파괴
            Destroy(gameObject);
        }
    }
}

이 코드에서 Singleton<T> 클래스는 제네릭 클래스로, 어디서든 싱글톤을 쉽게 구현할 수 있도록 해줍니다.

Step 2: 구체적인 싱글톤 클래스 만들기

이제 구체적인 싱글톤 클래스를 만들어보겠습니다. 예를 들어, 게임 매니저 클래스를 만들어보겠습니다.

public class GameManager : Singleton<GameManager>
{
    // 게임 점수를 저장하는 변수
    public int score;

    // 싱글톤 인스턴스를 초기화하는 메서드
    protected override void Awake()
    {
        base.Awake();
        // 초기화 코드 작성
        score = 0;
    }

    // 점수를 추가하는 메서드
    public void AddScore(int value)
    {
        score += value;
    }
}

이제 GameManager 클래스는 어디서든 GameManager.Instance를 통해 접근할 수 있습니다.

Step 3: 싱글톤 사용하기

게임 내에서 싱글톤 객체를 사용하는 방법은 다음과 같습니다.

public class Player : MonoBehaviour
{
    void Start()
    {
        // GameManager 싱글톤 인스턴스를 통해 점수를 추가
        GameManager.Instance.AddScore(10);
    }
}

이처럼 GameManager.Instance를 통해 전역적으로 접근할 수 있으며, 해당 인스턴스의 메서드나 변수에 접근할 수 있습니다.

주의사항

  1. 멀티스레딩 환경: 유니티는 기본적으로 싱글 스레드로 작동하기 때문에 멀티스레딩 이슈는 거의 없지만, 멀티스레딩을 사용할 경우 싱글톤의 스레드 안전성을 고려해야 합니다.
  2. 씬 전환: DontDestroyOnLoad(gameObject)를 사용하여 씬이 전환되어도 객체가 파괴되지 않도록 합니다.
  3. 메모리 관리: 불필요한 객체가 메모리에 남아있지 않도록 주의해야 합니다.

결론

싱글톤 패턴은 유니티 게임 개발에서 매우 유용하게 사용할 수 있는 디자인 패턴입니다. 전역 상태 관리, 자원 절약, 코드 구조의 간소화 등 많은 장점을 제공합니다. 위에서 설명한 단계를 따라 싱글톤 패턴을 구현하고, 여러분의 프로젝트에 적용해보세요!