싱글톤을 생성 방법

2015. 1. 30. 11:14C# And Unity

http://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();