게임엔진관련/유니티 엔진

[Unity] 유니티에서 싱글톤(Singleton) 사용하기 관련

AlrepondTech 2019. 3. 12. 15:28
반응형



 

 

=======================

=======================

=======================

 

 

 

 

//아래와 같이 만들고 상속하여 사용한다. 

public class CSingleton<T> : MonoBehaviour where T : class, new()

{

    protected static T _inst = null;

 

    public static T Inst

    {

        get

        {

            if (_inst == null)

            {

                _inst = new T();

            }

 

            return _inst;

        }

    }

}

 

 class MyClass : Singleton<MyClass>

    {

        // contents

        public void Print()

        {

             Log("Singleton OK");

        }

    }

 

//------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------

//싱글톤 생성하면서 Init()초기화용 함수추가 소스(싱글톤 생성시 초기화가 필요할때 필요한 부분)

 

 

 

 

//----------------------------------------------

//기본 싱글톤

 

public class CSgtBase

{

    public virtual void InitSgt() {}

}

 

public class CSingleton<T> : CSgtBase where T : CSgtBase, new()

{

    protected static T _inst = null;

 

    public static T Inst

    {

        get

        {

            if (_inst == null)

            {

                _inst = new T();

                _inst.InitSgt();

            }

 

            return _inst;

        }

    }

}

 

 

 

 

//-------------------------------------------------------

//유니티 오브젝트 싱글톤

 

public class CSgtGObjBase : MonoBehaviour

{

    public virtual void InitSgt() {}

}

 

public class CSingletonGObj<T> : CSgtGObjBase where T : CSgtGObjBase

{

    protected static T _inst;

 

    public static T Inst

    {

        get

        {

            if (_inst == null)

            {

                GameObject obj;

 

                obj = GameObject.Find(typeof(T).Name);

 

                if (obj == null)

                {

                    obj = new GameObject(typeof(T).Name);

                    _inst = obj.AddComponent<T>();

                    _inst.InitSgt();

 

                    DontDestroyOnLoad(obj);

                }

                else

                {

                    _inst = obj.GetComponent<T>();

                }

            }

 

            return _inst;

        }

    }

}

 

 

 

 



=======================

=======================

=======================

 

 

 

 

출처: https://karl27.tistory.com/54

 

C# 싱글톤 패턴 상속용 클래스

알게된 배경

싱글톤 패턴은 비교적 자주 사용되는 패턴이고, 멀티 스레드 프로그램을 작성할 경우 서로 상성이 안좋기 때문에 크리티컬 섹션에 대해서 뮤텍스(C#에서는 락)을 잡아줘야 한다. 문제는 이러한 패턴은 매번 반복이 되기 때문에 부모 클래스로서 작성을 해놓고, 상속받아서 기능을 구현하는 것이 여러모로 편리하다고 생각이 들기 때문에 찾아보니 해당 패턴이 있었다.

 그래서 메모겸 샘플 코드를 남긴다

 

부모 싱글톤

예시)

namespace Single {     public class Singleton<T> where T : class, new()     {         protected static object _instanceLock = new object();         protected static volatile T _instance;         public static T Instance         {             get             {                 lock(_instanceLock)                 {                     if(null == _instance)                          _instance = new T();                 }                 return _instance;             }         }      } } 

 

 

자식 싱글톤

예시)

namespace Single {     class MyClass : Singleton<MyClass>     {         // contents         public void Print()         {             Console.WriteLine("Hello Singleton?");         }     } } 

 

 



출처: https://karl27.tistory.com/54 [불확정한 세상]

 



=======================

=======================

=======================

 

 

 

출처: https://sillyknight.tistory.com/30

 

 

Unity Singleton을 제네릭으로 만들어놓고 써봅시다.

 

 

안녕하세요.

 

오늘은 유니티에서 자주 사용하는 대표적인 디자인 패턴인 Singleton을 쉽게 사용하기 위하여 제네릭으로 만들 겁니다.

 

제네릭이란 C++ 을 사용하신 분은 다들 아시는 템플릿과 비슷한 개념인데요.

 

유니티를 사용하는 상황에서는 C#을 쓰기 때문에 C++과는 차이점이 존재합니다.

 

아래는 Msdn에서 정의되어 있는 C#의 제네릭과 C++의 템플릿과의 주요 차이점입니다.

 



  • C# 제네릭은 C++ 템플릿과 같은 정도의 융통성을 제공하지 않습니다. 예를 들어, C# 제네릭 클래스에서 사용자 정의 연산자를 호출할 수는 있지만 산술 연산자를 호출할 수는 없습니다.
  • C#에서는 template C<int i> {} 같은 비형식 템플릿 매개 변수를 허용하지 않습니다.
  • C#에서는 명시적 특수화를 지원하지 않습니다. 즉, 특정 형식에 대한 템플릿을 사용자 지정하여 구현할 수 없습니다.
  • C#에서는 부분 특수화를 지원하지 않습니다. 즉, 형식 인수의 하위 집합을 사용자 지정하여 구현할 수 없습니다.
  • C#에서는 형식 매개 변수를 제네릭 형식에 대한 기본 클래스로 사용할 수 없습니다.
  • C#에서는 형식 매개 변수에 기본 형식을 사용할 수 없습니다.
  • C#에서는 생성된 형식을 제네릭으로 사용할 수는 있지만 제네릭 형식 매개 변수 자체가 제네릭이 될 수는 없습니다. C++에서는 템플릿 매개 변수를 허용합니다.
  • C++에서는 템플릿의 모든 형식 매개 변수에 대해서는 유효하지 않을 수 있는 코드가 허용되며 이러한 코드는 형식 매개 변수로 사용되는 특정 형식에 대해 검사를 받습니다. C#에서는 제약 조건을 충족하는 모든 형식과 함께 사용할 수 있도록 클래스의 코드를 작성해야 합니다. 예를 들어, C++의 경우 형식 매개 변수의 개체에 대해 +  - 산술 연산자를 사용하는 함수를 작성할 수 있습니다. 이 경우 이러한 연산자를 지원하지 않는 형식으로 템플릿을 인스턴스화할 때 오류가 발생합니다. C#에서는 이러한 함수를 작성할 수 없고 제약 조건에서 추론 가능한 언어 구문만 사용할 수 있습니다.

 

이것 외에도 구현 부분에서 가장 큰 차이점은 C#의 제네릭 형식 대체는 런타임에 수행되므로 인스턴스화된 개체에서 

 

제네릭 형식 정보가 유지된다는 점입니다.

 

위에 부분을 숙지 하시고 제네릭을 만들어 봅시다. 

 

 

using UnityEngine;


public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {


    private static T instance;
    


    public static T Instance
    {
        get
        {
            if(instance == null)
            {


                GameObject obj;
                obj = GameObject.Find(typeof(T).Name);
                if (obj == null)
                {
                    obj = new GameObject(typeof(T).Name);
                    instance = obj.AddComponent<T>();
                }
                else
                {
                    instance = obj.GetComponent<T>();
                }
            }
            return instance;
        }
    }


    public void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }


}

 

 

자 위와 같이 비교적 쉽게 만들 수 있는데요. Manager를 만들 시 우리는 보통 Singleton 형태로 만드는데요. 아래와 같이 하

 

시면 끝입니다.

 

 

using UnityEngine;


public class Manager: Singleton<Manager> {
 
}

 

 

다들 즐거운 코딩하시고 싱글톤은 앞으로 제네릭으로 만들어 놓고 편하게 쓰시길 바랍니다.

 

감사합니다.



출처: https://sillyknight.tistory.com/30 [실리의 Unity 게임 세상]

 

 



=======================

=======================

=======================

 

 

 

 

출처: http://lonpeach.com/2017/02/04/unity3d-singleton-pattern-example/

 

Unity3d Singleton 패턴을 사용하는 방법

 

01. 싱글톤 패턴

싱글톤 패턴이란?

싱글톤 패턴은 가장 많이 알려진 패턴 중 하나입니다.

본질적으로 싱글톤은 자신의 단일 인스턴스만 생성될 수 있게 해주는 클래스이며 일반적으로 해당 인스턴스에 대한 간단한 액세스를 제공합니다.

일반적으로 유니티에서 매니저 클래스나 컨트롤러 클래스를 싱글톤으로 만들어서 관리해 주는 편입니다.

유니티에서의 싱글톤은 2가지 버전으로 구분할 수 있습니다.

  1. C# 싱글톤 버전
  2. Monobehaviour 버전

기존에는 싱글톤 패턴을 사용할 때 내가 편한 방식으로 사용을 했었고 가장 간단한 방식을 선호 했었는데. 조금은 안전한 싱글톤 패턴을 사용하기 위해서 고민이 필요할 것 같다.

1. C# 싱글톤 버전

스레드 세이프 하지 않은 버전

// Bad code! Do not use! public sealed class Singleton {     private static Singleton instance=null;      private Singleton()     {     }      public static Singleton Instance     {         get         {             if (instance==null)             {                 instance = new Singleton();             }             return instance;         }     } } 

간단히 구현된 스레드 세이프 한 버전

public sealed class Singleton {     private static Singleton instance = null;     private static readonly object padlock = new object();      private Singleton()     {     }      public static Singleton Instance     {         get         {             lock (padlock)             {                 if (instance == null)                 {                     instance = new Singleton();                 }                 return instance;             }         }     } } 

스레드 세이프한 방법을 사용하자.

제네릭을 사용한 방법

using System;   using System.Reflection;    public class Singleton<T> where T : class   {       private static object _syncobj = new object();       private static volatile T _instance = null;       public static T Instance    {          get          {              if (_instance == null)              {                  CreateInstance();              }              return _instance;          }      }       private static void CreateInstance()      {          lock (_syncobj)         {             if (_instance == null)             {                 Type t = typeof(T);                  // Ensure there are no public constructors...                 ConstructorInfo[] ctors = t.GetConstructors();                 if (ctors.Length > 0)                 {                     throw new InvalidOperationException(String.Format("{0} has at least one accesible ctor making it impossible to enforce singleton behaviour", t.Name));                 }                  // Create an instance via the private constructor                 _instance = (T)Activator.CreateInstance(t, true);              }          }          }    }   

리플렉션 기능을 사용하여 생성된 인스턴스 수를 체크 후 1개 이상이면 익셉션 에러를 띄운다.

2. Monobehaivour 버전

간단한 방법

using UnityEngine; using System.Collections;  public class Singleton: MonoBehaviour {     public static Singleton instance = null;              //Static instance of GameManager which allows it to be accessed by any other script.      //Awake is always called before any Start functions     void Awake()     {         //Check if instance already exists         if (instance == null)         {                     //if not, set instance to this             instance = this;         }         //If instance already exists and it's not this:         else if (instance != this)         {                     //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.             Destroy(gameObject);             }             //Sets this to not be destroyed when reloading scene         DontDestroyOnLoad(gameObject);     } } 

Generic을 사용한 방법

using UnityEngine; using System.Collections;  /// <summary> /// Be aware this will not prevent a non singleton constructor ///   such as `T myT = new T();` /// To prevent that, add `protected T () {}` to your singleton class. /// As a note, this is made as MonoBehaviour because we need Coroutines. /// </summary> public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour {     private static T _instance = null;     private static object _syncobj = new object();     private static bool appIsClosing = false;      public static T Instance     {         get         {             if (appIsClosing)                 return null;              lock (_syncobj)               {                   if (_instance == null)                 {                     T[] objs = FindObjectsOfType<T>();                      if (objs.Length > 0)                         _instance = objs[0];                      if (objs.Length > 1)                         Debug.LogError("There is more than one " + typeof(T).Name + " in the scene.");                      if (_instance == null)                     {                         string goName = typeof(T).ToString();                         GameObject go = GameObject.Find(goName);                         if (go == null)                             go = new GameObject(goName);                         _instance = go.AddComponent<T>();                     }                 }                 return _instance;             }         }     }      /// <summary>     /// When Unity quits, it destroys objects in a random order.     /// In principle, a Singleton is only destroyed when application quits.     /// If any script calls Instance after it have been destroyed,     ///   it will create a buggy ghost object that will stay on the Editor scene     ///   even after stopping playing the Application. Really bad!     /// So, this was made to be sure we're not creating that buggy ghost object.     /// </summary>     protected virtual void OnApplicationQuit()     {         // release reference on exit         appIsClosing = true;     } } 

사용 방법

public class Manager : Singleton<Manager> { 	protected Manager () {} // guarantee this will be always a singleton only - can't use the constructor!  	public string myGlobalVar = "whatever"; } 

Generic을 사용한 방법에서는 Singleton을 상속받은 클래스에서는 생성자를 반드시 protected로 선언을 해서 외부에서는 생성이 되지 않게 막는다.

그리고 Singleton 클래스의 applicationIsQuitting 변수의 경우 별로 깨끗하지 않은 방법인것 같지만.. 유니티 에디터 상에서 갑자기 나가버리는 경우에 에러가 발생하는 경우라 반드시 필요한 변수이다. 이렇게 로직을 처리할 시에는 instance가 null이 나오는 경우가 생기므로 null 처리를 따로 처리해줘야 된다.

만약에 씬이 변환 되도 파괴되지 않은 싱글톤을 만들고 싶을 시에는 상속받은 클래스의 awake 함수에 아래와 같이 선언한다.

DontDestroyOnLoad(this.gameObject); 의 함수를 실행시켜 주자.

 

 

 

 

반응형

 

 

728x90

 

 

 

 



=======================

=======================

=======================

 

 

 

 

출처: https://unityindepth.tistory.com/38

 

원문 보기


유니티에서 싱글톤을 만드는 4가지 방법

여기 유니티에서 싱글톤(Singleton)을 사용하는 여러가지 방법이 있다. 

1) 일반적인 방법,
2) "자체 포함" 방법,
3) 빠르지만 지저분한 방법,
4) C#을 사용하는 사람들을 위한, 접근자 방법

1. 일반적인 방법

일반적인 방법은, GameObject에 첨부된 클래스에 정적 "GetInstance()" 함수를 만드는 것이다. 그리고 instance변수에 대해서 확인을 한다. 만약 instance가 null이 아니면 instance값을 반환하고, null인 경우, 클래스(여기서는 MyClass)를 첨부한 게임오브젝트를 하나 추가해야된다는 경고 메시지를 출력한다.
  1. public class MyClass  
  2. {  
  3.     private static MyClass instance;  
  4.     public static MyClass GetInstance()  
  5.     {  
  6.         if (!instance)  
  7.         {  
  8.             instance = GameObject.FindObjectOfType(typeof(MyClass));  
  9.             if (!instance)  
  10.                 Debug.LogError("There needs to be one active MyClass script on a GameObject in your scene.");  
  11.         }  
  12.    
  13.         return instance;  
  14.     }  
  15. }  

여기서 GameObject.FindObjectOfType(typeof(MyClass));은 씬에서 MyClass타입에 대한 첫번째 활성화 된 게임 오브젝트를 반환한다. 만약 좀 더 안전하게 검사를 하고 싶다면, GameObject.FindObjectsOfType(typeof(MyClass))를 사용하여 MyClass타입에 대한 활성화된 모든 객체의 배열을 얻은다음, Length를 검사하면 된다. Length > 1일 경우 여러 객체가 씬에 존재한다는 의미이기때문에, 삭제를 하거나 다른 특별한 조치를 취해야 할 것이다.


2
. 
"자체 포함" 방법 

게임이 실행되던 도중에, 씬에서, 많은 수의 게임 오브젝트가 단순히 클래스(스크립트)만을 가지고 있다는 사실을 알게 되었다. 그래서 나는 "자체 포함" 싱글톤을 만들었다. 만약 instance를 찾지 못하면, 클래스에서 스스로GameObject를 만들고, AddComponent() 함수를 이용해 GameObject에 해당 클래스 인스턴스를 첨부한다. 이 방법을 사용하면, 더 이상 IDE에서 게임 오브젝트를 만들지 않아도 되고, 디자인 작업을 할 때 씬이 어수선하지 않게 해준다.
  1. public class Logger : MonoBehaviour  
  2. {  
  3.         private static Logger instance;  
  4.         private static GameObject container;  
  5.         public static Logger GetInstance()  
  6.         {  
  7.                 if( !instance )  
  8.                 {  
  9.                         container = new GameObject();  
  10.                         container.name = "Logger";  
  11.                         instance = container.AddComponent(typeof(Logger)) as Logger;  
  12.                 }  
  13.                 return instance;  
  14.         }  
  15. }  
  16.    

3. 빠르지만 지저분한 방법.

이 방법은 아주 간단하다. 클래스에 정적 변수로 instance를 만들고 Awake()함수에서 이를 초기화 한다음, GameObject에 이 스크립트를 붙이기만 하면 된다. 이것이 전부다. 

사용 법 : MyClass.instance.DoSomething();

  1.    
  2. public class MyClass  
  3. {  
  4.         public static MyClass instance;  
  5.         public void Awake()  
  6.         {  
  7.                 MyClass.instance = this;  
  8.         }  
  9. }  
 

4. 접근자 방법(only c#)

위에 나왔던 1번과 2번 방법은 함수보다 프로퍼티(속성)를 이용해서 좀 더 개선할 수 있다.
  1.    
  2. public class MyClass  
  3. {  
  4.         private static MyClass _instance;  
  5.         public static MyClass Instance  
  6.         {  
  7.                 get  
  8.                 {  
  9.                         if (!_instance)  
  10.                         {  
  11.                                 _instance = GameObject.FindObjectOfType(typeof(MyClass));  
  12.                                 if (!_instance)  
  13.                                 {  
  14.                                         GameObject container = new GameObject();  
  15.                                         container.name = "MyClassContainer";  
  16.                                         _instance = container.AddComponent(typeof(MyClass)) as MyClass;  
  17.                                 }  
  18.                         }  
  19.   
  20.                         return _instance;  
  21.                 }  
  22.         }  
  23. }  
  
이 방법은 3번 방법과 똑같이 다음과 같은 방법으로 쉽게 사용할 수 있다:
MyClass.Instance.DoSomething();



출처: https://unityindepth.tistory.com/38 [UNITY IN DEPTH]

 



=======================

=======================

=======================

 

 

 

 

출처: http://rapapa.net/?p=3198

 

 

[ Programming Pattern 시리즈 ]
싱글턴 패턴 (Singleton Pattern) Link
컴포넌트 패턴 (Component Pattern) Link

커멘드 패턴 (Command Pattern) Link
관찰자 패턴 (Observer Pattern) Link
상태 패턴 (State Pattern) Link

Singleton Pattern의 GoF 정의는 아래와 같다.

“오직 한 개의 클래스 인스턴스만을 갖도록 보장하고, 이에 대한 전역적인 접근점을 제공합니다”

싱글턴 패턴은 게임 개발자들이 많이 사용하는 패턴이다. 특히 Manager류의 클래스를 만들거나, 오디오, 이벤트 등 디바이스 I/O를 다루는 곳에서도 자주 쓰인다.

유니티에서 싱글톤 객체를 구현하는 방법은 Scene에 빈객체를 생성한 후에 오직 하나의 객체만 생성되도록 만들고, DontDestroyOnLoad 메쏘드를 호출하여 Scene 변경시에도 Destroy를 막아주는 형태로 구현한다. 아래는 그 예이다.

 

<GameManager.cs>

이렇게 구현 해 놓으면 게임 내부의 어느 곳에서든지 GameManager.instance 로 모두 접근 가능하고, 하나의 객체로 중복 생성 없이 객체를 유지할 수 있다.

또한 싱글턴 객체를 상속하여 유익한 구조를 만들 수도 있다. 다음은 C++ 코드로 PS3와 NDS 파일 시스템 구분을 싱글턴 객체를 상속하여 손쉽게 구현하는 방식이다.

이렇게 구현해 놓으면 다른 모든 클래스에서는 플랫폼의 구분을 할 필요 없이 FileSystem.instance 호출 만으로 플랫폼에 맞는 File System을 획득하게 된다.

이처럼 싱글턴은 여러모로 유용하게 사용할 수 있으나 의외로 싱글턴이 문제를 일으키는 경우도 많다. 그래서 많은 개발자들이 싱글턴의 사용을 즐겨하지만 또 많은 개발자들이 싱글턴 오용의 위험성을 경고한다.

왜냐하면, 싱글턴은 일종의 전역 변수이기 때문이다.
전역 변수이므로 전역 변수가 가지는 모든 장점과 단점을 다 가지고 있다. 모든 곳에서 접근 가능하니, 객체의 변경 시점과 변경 주체를 알기가 쉽지 않다. 호출하는 모든 코드들을 다 뒤져야 할 수 있다. 또한 전역 변수이기 때문에 여러 클래스와 Coupling이 된다. 하나의 코드를 수정했을 때 싱글턴과 연결된 다양한 곳에서 문제를 발생 시킬 수 있는 것이다. 가능한한 Instance 접근을 통제하는 것이 결과적으로 더 적은 버그를 만들게 한다. 또한 전역 변수이기 때문에 멀티 쓰레드의 환경에서는 문제가 발생한다. 모든 곳에서 접근 가능하기 때문에 race condition이 발생할 수 있다. 그걸 피하기 위해서 필연적으로 싱글턴에선 mutex lock과 unlock을 반복해서 걸게 되는게 자연히 코드 전체적으로 Performance가 떨어지는 문제가 발생한다. 유니티 C#에서는 싱글톤에 연결된 reference 객체들이 사용이 끝났음에도 불구하고 null을 먹여주지 않으면 GC로 넘어가지 않는 문제도 발생한다.

Singleton의 대안으로는 가능한 Manager류의 생성을 피하고 각 클래스 안으로 코드를 집어 넣는 것이다. 또한 전역 접근이 불가능한 Singleton을 만드는 것도 방법이다. 대신 클래스끼리 서로 넘겨주고 받으면서 사용하거나, 상위 클래스로부터 얻거나, 이미 전역인 객체 안에 위치시켜서 접근 방식 자체를 줄이는 것도 생각해 볼 수 있다.

 



=======================

=======================

=======================

 

 

 

출처: https://bluemeta.tistory.com/16

 

1. 싱글턴 패턴

 싱글턴 패턴이란 소프트웨어 디자인 방법 중에 하나입니다.

 유니티로 게임을 개발하다보면 여러 게임오브젝트가 접근해야하는 스크립트가 있을 수 있습니다. 대표적으로 게임매니저(GameManager) 역할을 하는 스크립트인데요. 게임의 전체 볼륨을 조절한다거나 난이도 설정, 오브젝트 풀 관리 등의 목적으로 게임매니저 스크립트를 만들어 사용하곤 합니다. 이렇듯 단일 시스템 자원을 관리하는 타입이 필요한 경우가 있습니다.

 

전체 게임(씬)의 자원을 관리하는게임매니저 스크립트. 사람들이 정말 많이 사용하는지 유니티 에디터에서 전용 아이콘도 만들어줍니다. ^^

(절대강좌! 책 공부 중...)

 

 게임매니저 스크립트와 같은 경우는 여러 스크립트에 영향을 줍니다. 그리고 일종의 전역변수(static variable)과 같은 역할도 겸하고 있습니다. 즉, 많은 다른 스크립트가 하나의 스크립트에 접근해야하고 접근할 때 스크립트마다 각각 인스턴스화하는 것이 아니라 하나의 인스턴스로 충분할 경우(전역 변수의 역할과 똑같죠?) 싱클턴 패턴을 사용하는 것이 효과적입니다.

 싱글턴은 최초로 생성된(클래스가 메모리에 로드될 때 만들어지는) 인스턴스만 존재하고 이후에는 생성 자체가 불가능(private하다는 의미겠죠?)한 소프트웨어 디자인 방법입니다.

 

 

2. 유니티에서 싱글턴 패턴 만드는 방법

 싱글턴 패턴을 만드는 방법은 여러 방법이 있고 이론적으로도 복잡하지만. 유니티에서 싱글턴 패턴을 만드는 방법은 아주 간단합니다.

 아래 코드를 확인해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GameManager : MonoBehaviour {
 
    public static GameManager instance;
 
    public int level;
 
    void Awake () {
        instance = this;
    }
    
}
cs

 

 GameManager 타입의 전역 변수 instance를 선언한 후 Awake() 메소드에서 this를 할당해주면 바로 싱클턴 패턴을 만들 수 있습니다. 즉, 재귀적으로 자기 자신의 참조변수를 선언하고 this 키워드로 설정하면 됩니다. Awake() 메소드를 사용하는 이유는 GameManager 스크립트가 씬에 생성되자마자 싱글턴 인스턴스를 만들기 위함입니다. 이렇게 하면 별도의 GetComponent<GameManager>() 메소드를 사용하지 않고도 instance 변수에 접근할 수 있습니다. 다음과 같이 말이죠.

1
2
3
4
5
6
7
8
9
10
11
12
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class WormCtrl : MonoBehaviour {
 
    void Start ()
    {
        GameManager.instance.hp = 100;
    }
 
}
cs

 

 WormCtrl이라는 스크립트에서 별도의 코드 없이 GameManager.instance 인스턴스에 접근할 수 있습니다. 그리고 GameManager의 hp를 바로 설정할 수 있고 다른 모든 스크립트에서 이 hp값을 공유합니다. 아주 편리한 기능이죠.

 

 

3. 싱글턴 패턴의 접근제한자

 싱글턴 인스턴스가 가지고 있는 필드와 프로퍼티는 기본적으로 public이어야 합니다. 그렇지 않으면 다른 스크립트에서 싱글턴 인스턴스에 접근하더라도 해당 필드, 프로퍼티는 사용할 수 없기 때문입니다. 물론 싱글턴 내부에서만 사용할 경우에는 private라도 상관없겠지요.

 

 

4. 정리

  1. 싱글턴 패턴은 디자인 패턴 중 하나로 단일 시스템 자원을 관리하는 인스턴스이다.
  2. 싱글턴 패턴으로 만든 싱글턴 인스턴스는 게임(씬) 내에 하나만 존재한다. 
  3. 싱글턴 패턴은 자기 자신을 타입으로 하는 참조변수의 선언과 Awake() 메소드에서 this 키워드로 그 참조변수를 설정하면 바로 사용 가능하다. 
  4. 싱글턴 패턴의 필드, 프로퍼티는 그 성격상 접근제한자를 public으로 하는 것이 좋다.

 



=======================

=======================

=======================

 

 

반응형