프로그램 내부에 유일하게 존재하는 오브젝트
GameManager
, SoundManager
같이 특정한 하나의 기능을 가진 오브젝트를 만들 때 사용함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을 선언할 경우, 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.");
}
}