프로젝트 안의 자원을 매니저라는 하나의 클래스 안에서 관리하고 싶을 때, 소프트웨어 공학에서 배웠던 싱글톤 패턴을 떠올릴 수 있다.
https://guhonga.tistory.com/148
이름 그대로, 특정 클래스의 인스턴스가 하나만 있기를 원할 때 사용하는 디자인 패턴이다.
다른 오브젝트의 컴포넌트에서 언제 어디서든 편하게 매니저 클래스를 사용하여 관리할 수 있다면 좋을 것이다.
예를 들어 Player 클래스에서 Manager 클래스를 불러오고 싶다면, 우선 MonoBehaviour 클래스 안에 있는 GameObject.Find를 사용하여 우리가 원하는 오브젝트의 이름이 있는지 확인하는 방법을 떠올릴 수 있다.
GameObject go = GameObject Find("Managers");
Manager mg = go.GetComponent<Manager>();
Managers 오브젝트 안에 넣은 Manager 컴포넌트 (스크립트)를 찾아서 mg에 할당해줬다.
그런데 매번 매니저를 불러올 때 마다 매니저 오브젝트 이름을 찾는 것은 엄청난 비효율이다.
게다가, 만약에 Manager 스크립트가 여러 오브젝트에 추가되어 있으면, 하나의 매니저만 있어야 하는 싱글톤의 디자인 패턴 자체가 모순되는 상황이 생긴다.
그래서 싱글톤으로 구현하기 위해서 우리는 static을 이용하여 전역으로 사용하는 변수를 하나 Manager 클래스에 만들어준다.
static Manager s_instance; // 유일함
public static Manager Instance { get {Init(); return s_instance; } } // 프로퍼티 사용
static으로 선언함으로서 유일성이 보장되고, 외부에서 manager를 사용하고 싶다면 s_instance 프로퍼티를 통해서만 사용할 수 있다.
즉, 유일한 매니저를 갖고 온다는 의미이다.
전역으로 선언되어 있기 때문에, 각기 다른 컴포넌트에서 호출해도 모두 동일한 매니저를 사용하게 된다.
이렇게 Manager 타입 변수 s_instance를 선언해줬는데, 여기에 this 키워드를 이용해서 자기 자신을 할당해준다.
s_instance = this;
여기에서 this는 처음에 생성된 manager라는 컴포넌트 자기 자신을 할당한다는 의미이다.
그런데 이렇게 되면, 이 스크립트를 가진 객체들마다 자기가 매니저라며 매번 다시 새롭게 할당할테니
this로 매니저를 할당해주는 것보다 이름으로 매니저를 할당해주자.
(매니저 클래스 내부에서 한번만 할당해주면 되니까 아까 Player 클래스마다 이름으로 찾지 않아도 된다.)
GameObject go = GameObject Find("Managers");
Manager mg = go.GetComponent<Manager>();
그럼 아무리 각각의 매니저 컴포넌트들이 static 인스턴스를 호출해도 전역에 저장되는 것은 manager 원본일 것이다.
이렇게 manager를 설정해줬으면
앞으로 각각의 Player 객체는 아래와 같이 static으로 정의된 유일한 manager를 갖고와서 사용할 수 있다.
Managers mg = Managers.GetInstance();
이제 문제 없는것 같아 보이지만, 만약에 manager 클래스에서 Find() 했던 해당 매니저의 이름이 없다면
매니저 변수에는 null 이 할당되고, 이것에 접근하는 오브젝트가 있을 시 프로그램은 크래시가 날 것이다.
결국, 그냥 이름만 찾아서 s_instance에 할당해주는 것은 안된다.
Manager 클래스의 s_instance할당 부분을 초기화해주는 Init() 함수로 새롭게 만들어보자.
static void Init()
{
if (s_instance == null)
{
GameObject go = GameObject.Find("Managers");
if (go == null)
{
go = new GameObject { name = "Managers" };
go.AddComponent<Manager>();
}
DontDestroyOnLoad(go);
s_instance = go.GetComponent<Manager>();
}
}
이제 instance가 null이라면 해당 오브젝트가 있는지 찾아보고,
오브젝트가 존재하지 않는다면 새로 오브젝트와 컴포넌트(스크립트)를 추가해준다.
이제 할당된 것을 확인했으면, static Instance 에 Manager를 할당해준다.
이런 과정을 통해서 우리는 유일한 Manager Instance를 얻을 수 있다.
만약 다른 Player 객체에서 Manager를 호출하고 싶다면
Managers mg = Managers.Instance;
이렇게 바로 호출해서 사용할 수 있다.
레퍼런스
https://www.inflearn.com/course/mmorpg-%EC%9C%A0%EB%8B%88%ED%8B%B0/dashboard