본문 바로가기

Engine/Unity 그때그때 끄적끄적

[Unity] 싱글톤 패턴

싱글톤이란 디자인 패턴의 일환으로 말그대로 객체를 하나만 생성하고, 생성된객체를 어디에서든 참조하여 사용하는 패턴을 의미한다.

 

아래는 Monobehaviour를 상속받은 싱글톤 패턴의 모습이다

public class GameManager : MonoBehaviour
{
    private static GameManager instance = null;
    
    // 어디서든 접근 가능한 프로퍼티
    public static GameManager Instance
    {
        get     
        {
            if (null == instance)
            {
                return null;
            }
            return instance;
        }
    }
    
    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            // 인스턴스가 없다면 해당 인스턴스를 넣어줌

            DontDestroyOnLoad(this.gameObject);
            // 씬이 변화하여도 삭제되지않게함
        }
        else
        {
            Destroy(this.gameObject);
            // 만약 새롭게 인스턴스를 생생했다면 생성한 인스턴스를 삭제함
        }
    }
}

모든생성자를 private로만들어 접근하지 못하게만들고

해당 컴포넌트 타입의 인스턴스를 static 으로 만들어 단하나만 존재할 수 있도록 만든 후

public 프로퍼티를 활용하여 해당 변수에 접근할 수 있도록 하는방식으로 싱글톤 패턴을 활용한다

 

Awake 함수에서 인스턴스의 중복검사 통해 새로생성된 싱글톤 인스턴스를 삭제하는 작업을 진행한다

만일 존재하지않는다면 오브젝트를 할당하고 DontDestroyOnLoad함수를 통해 씬이 전환되어도 오브젝트가 파괴되지않게 하는것으로 싱글톤 패턴이 완성된다.

 

 

싱글톤의 장단점

 

장점

  • 오브젝트를 찾고 스크립트를 찾는 과정을 거치지않아도 프로퍼티로 쉽게 접근할 수 있어서 편하다
  • 게임 내에 하나만존재하기때문에 쓸때없이 중복되는 현상을 방지할 수 있다
  • 고정 메모리 영역을 얻기에 메모리활용에도 유리하다

단점

  • 편하기때문에 위험하다 접근이 편하기에 마구잡이로 코드들을 싱글톤에 밀어넣는 실수를 범할 경우 싱글톤이 너무 비대해져서 자칫 객체지향을 해칠 가능성이 존재한다 때문에 적절하게 사용하는것이 중요하다

 

 

비슷하지만 조금다른버전

public class GameManager : MonoBehaviour
{
    private static GameManager instance = null;
    // 일반 적인 싱긅톤 패턴들은c# 클래스의 오브젝트들은 private로 외부에서 생성을 막지만
    // 유니티는 addcomponent()를 사용하여 게임오브젝트에 컴포넌터를 붙여야하므로
    // privte 만으로는 막을 수 없다 때문에 아래와 같이 중복을 검사하는 과정이 필요하다


    //게임 매니저 인스턴스에 접근할 수 있는 프로퍼티. static이므로 다른 클래스에서 맘껏 호출할 수 있다.
    public static GameManager Instance
    {
        get
        {
            if (instance == null)
            {
                var obj = FindObjectOfType<GameManager>();
                if (obj != null)
                {
                    instance = obj;
                }
                else
                {
                    var newgameManager = new GameObject("GAMEMANAGER").AddComponent<GameManager>();
                    instance = newgameManager;
                }
            }
            return instance;
        }
    }


    void Awake()                    // 생성시 싱글톤의 중복을 검사하여 중복되었다면 삭제함
    {
        if (instance == null)       // 중복되지않았을때
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
            // 씬이 변화하여도 삭제되지않게함
        }
        else
        {
            Destroy(this.gameObject);
            // 만약 새롭게 인스턴스를 생생했다면 생성한 인스턴스를 삭제함
        }
    }

}

처음에 오브젝트에 스크립트를 넣어 실행하는 위 버전과 다르게 처음 프로퍼티를 호출할 때 새롭게 게임오브젝트와 스크립트를 할당하여 생성하는 버전

'Engine > Unity 그때그때 끄적끄적' 카테고리의 다른 글

[Unity] 애니메이션  (0) 2021.07.30
[Unity] 네비게이션  (0) 2021.07.23
[Unity] 화면 전환  (0) 2021.07.14
[Unity] CSV파일 읽고 사용하기  (0) 2021.07.11
[Unity] Sprite Atlas 활용하기  (0) 2021.07.08