[Unity] Singleton(싱글톤) 동적 생성

Psychologist Dobby·2022년 9월 2일
0

Unity 공부

목록 보기
1/2

Singleton(싱글톤)

프로그램 내부에 유일하게 존재하는 오브젝트

사용하는 이유

  • 모든 scene에서 계속해서 사용하고 싶은 오브젝트
  • 단 하나의 오브젝트로 만들어 다른 오브젝트에서 접근할 때 검색이나 드래그 & 드롭을 사용하지 않고도 코드에서 바로 접근 가능하게끔 하기 위해
  • 보통 GameManager, SoundManager 같이 특정한 하나의 기능을 가진 오브젝트를 만들 때 사용함

단점

  • 코드 추적이 어려워질 수 있음
    여러 클래스에서 singleton 내부의 변수를 변경하거나 함수에 접근할 수 있기 때문!

간단 사용 예제

using UnityEngine;

public class AudioManager : MonoBehaviour
{
	private static AudioManager instance;
    public static AudioManager Instance {
    	get {
        	if (instance == null){
            	var obj = FindObjectOfType<AudioManager>();
                if (obj != null) {
                	intance = obj;
            	}
            	else {
                	// instance가 없으므로 새로 만들기
                    // "이름" 넣어 새로운 GameObject를 만들고
                    // AddComponent<클래스이름>() 통해 해당 클래스 가지게 만들기
                	GameObject go = new GameObject("AudioManager").AddComponent<AudioManager>();
                    instance = go;
                    //DontDestroyOnLoad(instance);
            	}
                return instance;
        	}
            
        }
        private set { instance = value; }
    }
	
    private void Awake() {
    	if (instance) {
        	if (instance != this) {
                // instance가 존재하는데
            	// 현재 오브젝트가 아니라면 다른 instance가 존재한다는 뜻이므로 현재 오브젝트 삭제
            	Destroy(gameObject);
            }
        }
    	
    }


}

static을 사용해 프로그램 내부에 딱 하나 존재하는 instance를 만들 수 있다.
Instance() 함수는 instance(싱글톤 객체)를 return하므로 다른 클래스에서 싱글톤에 접근할 때 항상 Instance() 함수를 사용한다.

필요에 따라 DontDestroyOnLoad()를 사용하여 Scene이 바뀌어도 싱글톤 오브젝트가 유지되게 할 수 있다.

Singleton 생성을 Generic으로 관리하기

여러 singleton을 선언할 경우, singleton 생성 부분을 담은 generic 클래스를 따로 만들어 이것을 각 클래스에서 상속하는 식으로도 사용 가능하다.
참고한 블로그는 여기 -> 앤디가이

using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;
    public static T Instance { 
        get { 
            instance = (T)FindObjectOfType(typeof(T));
            if (instance == null)
            {
                var obj = new GameObject().AddComponent(typeof(T)) as T;
                instance = obj;
                obj.name = typeof(T).ToString();

				// scene 바뀌어도 사라지지 않으려면
                //DontDestroyOnLoad(obj);
            }

            return instance; 
        } 

        set { instance = value; } 

    }
}

AudioManager가 위의 클래스를 상속한다면 아래와 같이 작성 가능하다.

using UnityEngine;

public class AudioManager : Singleton<AudioManager> {
	// singleton을 생성하고 찾는 부분은 Singleton<AudioManager>에 있으므로
	// AudioManager에서 사용할 함수만 적어주면 됨
    
    public void PlayMusic() {
    	Debug.Log("Play music.");
    }
	
}
profile
개발하는 심리학자

0개의 댓글