Programming 

유니티에서의 싱글톤 패턴 활용

 

[이 포스트의 내용은 유튜브 영상으로도 시청하실 수 있습니다]

 

여러 종류의 프로그램을 만들다 보면 어떤 문제를 해결하기 위해서 비슷한 형태의 코드를 만들게 되는 경우가 자주 있다. 이런 비슷한 유형의 문제를 해결하는 방법을 묶어낸 것을 바로 프로그래밍 패턴이라고 한다. 이러한 프로그래밍 패턴은 유니티 엔진에서 스크립트를 작성하는데도 똑같이 유효하기 때문에 프로그래밍 패턴을 공부하는 것이 상당한 도움이 될 것이다.

 

 

일반적인 싱글톤 패턴(Singleton Pattern)

 

싱글톤 패턴은 프로그래밍 패턴 중에서 상당히 자주 쓰이는 패턴 중 하나로, 클래스의 오브젝트를 단 하나만 생성하고자 할 때 주로 사용된다.

 

public class SingletonClass

{

    private SingletonClass()

    { }

 

    public static SingletonClass Instance

    {

        get

        {

            if (Instance == null)

            {

                Instance = new SingletonClass();

            }

            return Instance;

        }

        private set

        {

            Instance = value;

        }

    }

}

 

일반적인 C# 프로그래밍에서는 싱글톤 패턴이 위의 코드와 같이 구현된다. 기본 생성자를 private으로 지정해서 클래스 외부에서 호출하지 못하게 하여서 클래스 외부에서는 오브젝트를 생성할 수 없게 한다. 그리고 Instance라는 프로퍼티를 호출했을 때, Instance 프로퍼티가 비어있다면 처음 한 번 생성하고 그 뒤로를 생성한 Instance를 호출하는 식으로 구현한다.

 

위와 같은 방법으로 오브젝트를 하나만 생성가능하게 만드는 것이 바로 싱글턴 패턴이다. 싱글톤 패턴은 예를들어 센서와 통신하는 클래스처럼 단 하나만 존재해야하는 경우에 사용된다.

 

 

유니티 엔진에서의 싱글톤 패턴

 

유니티 엔진에서도 싱글톤 패턴을 응용해서 사용할 수 있다. 일단 유니티 엔진에서 일반 C# 클래스로 싱글톤 패턴을 사용한다면 위의 코드 예시와 똑같이 구현하면 된다. 하지만 모노비헤이비어를 상속받는 컴포넌트 클래스에서의 싱글톤 패턴 구현은 조금 달라진다.

 

우선 모노비헤이비어를 상속받는 컴포넌트 클래스와 일반 C# 클래스의 차이점을 알아둬야 한다.

 

var newSingleton = new GameObject("Singleton Class");

newSingleton.AddComponent<SingletonClass>();

 

우선, new 연산자를 통해서 생성되는 일반 C# 클래스의 오브젝트와 달리 컴포넌트 클래스의 오브젝트를 생성할 때는 게임 오브젝트를 생성한다음에 AddComponent() 함수를 이용해서 게임 오브젝트에 컴포넌트를 붙여줘야 한다. 그렇기 때문에 일반 C# 클래스와 같이 생성자를 private으로 바꾸는 방법으로는 클래스 외부에서의 오브젝트의 생성을 막을 수 없다.

 

뿐만 아니라, 이미 컴포넌트가 부착된 오브젝트가 씬에 만들어져 있는 경우도 있을 수 있고, 컴포넌트가 부착된 프리팹이 생성되는 경우까지 있다. 그렇기 때문에 일반 C# 클래스와 같이 생성자로 외부 생성을 막는 방법은 전혀 유효하지 않다.

 

public class SingletonClass : MonoBehaviour

{

    private static SingletonClass instance;

    public static SingletonClass Instance

    {

        get

        {

            if (instance == null)

            {

                var obj = FindObjectOfType<SingletonClass>();

                if (obj != null)

                {

                    instance = obj;

                }

                else

                {

                    var newSingleton = new GameObject("Singleton Class").AddComponent<SingletonClass>();

                    instance = newSingleton;

                }

            }

            return instance;

        }

        private set

        {

            instance = value;

        }

    }

 

    private void Awake()

    {

        var objs = FindObjectsOfType<SingletonClass>();

        if (objs.Length != 1)

        {

            Destroy(gameObject);

            return;

        }

        DontDestroyOnLoad(gameObject);

    }

}

 

컴포넌트 클래스의 특성에 유의해서 싱글톤 패턴을 작성하면 위의 예시 코드와 같이 구현된다.

 

우선, 일반 C# 클래스에서와 같이 instance가 null인지 검사를 하되 곧바로 오브젝트를 생성하지 말고 씬에 이미 게임 오브젝트에 부착된 싱글톤 클래스가 있는지 검사하고 만약, 이미 있다면 instance에 넣어준 뒤, instance를 반환한다. 씬에 존재하지 않는 상태라면, 싱글톤 클래스의 오브젝트가 컴포넌트로 부착된 게임 오브젝트를 생성하고 이를 반환한다.

 

그리고 게임 오브젝트가 생성되거나 컴포넌트가 게임 오브젝트에 부착되었을 때 가장 먼저 실행되는 Awake() 함수에서 씬에 이미 존재하는 같은 싱글톤 오브젝트가 있는지 검사를 한 뒤, 이미 존재하는 오브젝트가 있다면 지금 생성된 오브젝트를 파괴하는 작업을 진행한다.

 

마지막으로 씬을 전환할때 싱글톤 패턴이 적용된 오브젝트가 파괴되는 것을 막기 위해 DontDestroyOnLoad()를 적용해준다. 보통 유니티에서 싱글톤 패턴을 적용하는 경우는 시스템 매니저와 같이 시스템 전체를 관리하는 오브젝트처럼 여러 씬에서 살아있어야 하는 오브젝트가 대부분이다.

 

 

싱글톤 패턴의 장점과 유용성

 

public class SingletonTester : MonoBehaviour

{

    void Start()

    {

        var singleton = SingletonClass.Instance;

        singleton.Function();

    }

}

 

싱글톤 패턴의 장점과 유용성은 게임이나 프로그램에 단 하나만 존재해야하는 클래스를 다룰 때 나타난다. 단 하나만 존재해야 하는 클래스의 생성을 적절하게 통제할 수 있으며, 전체에 단 하나이기 때문에 따로 매번 오브젝트를 생성하거나 탐색해서 찾을 필요없이 instance 프로퍼티를 통해서 빠르게 접근할 수 있다.

 

 

싱글톤 패턴의 단점과 해악

 

싱글톤 패턴의 장점은 프로그램에 단 하나여야 하는 클래스의 오브젝트를 다루는데 뛰어난 효율성을 보여준다는 것인데, 어떤 개발자들은 빠르고 편하게 사용할 수 있다는 점에 주목한다. 그리고 싱글톤 패턴의 모든 단점과 해악성은 여기에서 나온다.

 

오브젝트를 따로 탐색하거나 생성할 필요가 없이 바로 instance 호출로 바로 가져올 수 있다는 점에 취해서 쉽게 남용되는 패턴이 바로 싱글톤 패턴이다. 이 때문에 조금이라도 가져오기 어려운 오브젝트가 있으면 싱글톤 패턴으로 만들어버리거나, 기능을 싱글톤 패턴을 가진 오브젝트에 합쳐버리는 우를 범하게 된다.

 

일이 이렇게 진행되기 시작하면, 여기저기서 각기 다른 클래스의 instance를 호출하는 구조로 코드의 흐름이 알기 어려워지고 싱글톤 패턴을 가진 오브젝트의 코드 크기는 점점 거대해져서 기형적으로 비대한 구조가 만들어지며, 나중에는 따로 분리해내거나 정리하기 어려워진다.

 

때문에 싱글톤 패턴을 사용할 때는 편리함에 너무 취하지 않아야 하며, 해당 클래스가 너무 비대화되지 않는지, 처리하기로 설계한 기능 이외의 것을 처리하려고 하고 있지 않은지를 끊임없이 경계해야 한다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts