# 매니저 클래스
클래스는 컴포넌트 클래스와 매니저 클래스로 구분된다
그런데 매니저 클래스는 아래의 코드에서처럼
new로 생성이 안 되는 문제가 발생한다
public class Managers : MonoBehaviour
{
void Start()
{
}
void Update()
{
}
}
public class Test : MonoBehaviour
{
void Start()
{
Managers mg = new Managers();
}
void Update()
{
}
}
그 이유는 MonoBehaviour 상속받은 클래스는
new로 객체 생성이 불가하기 때문이다
MonoBehaviour의 상속 구조는 아래와 같다
"MonoBehaviour -> Behaviour -> Component -> Object"
여기서 Object는 게임오브젝트에 붙일 수 있는 모든 기본(근본) 클래스를 의미한다
MonoBehaviour 상속을 받지 않고 만들면
정상적으로 new로 매니저 클래스 객체 생성은 가능하긴 하다
그러나 유니티 기능(ex. Start(), Update()) 활용이 불가하다
또한, 유니티는 Main문도 숨겨놓고 있기에
Main문에 매니저 클래스를 생성하지도 못하는 문제가 있다
결국, MonoBehaviour를 상속받아야 유니티에서
컴포넌트로 인식하고 탈착이 가능하다는 것이다
유니티에서 매니저 클래스를 어떻게 만들고 활용할지에 대한 결론은
바로 매니저 클래스는 MonoBehaviour를 상속받고
"실체가 없는 컴포넌트 클래스"로 활용을 하면 된다
빈 게임오브젝트에 해당 매니저 클래스를 컴포넌트로 붙여서 활용한다는 것이다
해당 게임오브젝트 이름 앞에 '@'를 붙여서 매니저 클래스임을 나타내는 컨벤션도 존재한다
# Sigleton 패턴
- 매니저 클래스를 가져오는 방법
GameObject.Find를 통해 가져올 수 있다
주의점은 해당 오브젝트의 매니저 클래스 컴포넌트를 들고 와야 한다
public class Player : MonoBehaviour
{
void Start()
{
GameObject go = GameObject.Find("@Manager")
Managers mg = go.GetComponent<Managers>()
}
void Update()
{
}
}
매번 매니저 클래스를 가져올 때
위처럼 이름으로 찾아오는 것은 성능 상으로 비효율적이다
- 유일성을 보장하기 위한 Sigleton을 활용하는 방법
매니저 클래스 컴포넌트가 붙은 객체는
단 하나만 존재해야 하는 것이 일반적이고 당연하다
그래서 Singleton 패턴을 활용해서 유일성을 보장할 수 있다
public class Managers : MonoBehaviour
{
static Managers Instance;
public static Managers GetInstance() { return Instance; }
void Start()
{
GameObject go = GameObject.Find("@Managers");
Instance = go.GetComponent<Managers>();
}
void Update()
{
}
}
public class Player : MonoBehaviour
{
void Start()
{
Managers mg = Managers.GetInstance();
}
void Update()
{
}
}
위의 코드에서
만약에 매니저 컴포넌트가 붙은 빈 객체("@Managers")를
유니티에서 만들어주지 않았다면 null을 반환하는 문제가 있다
이를 해결하기 위해서
null 여부에 따라서 직접 오브젝트 생성 및 컴포넌트를 부착하는 코드가 필요하다
또한, DontDestroyOnLoad를 통해 Scene 이동을 하더라도 삭제되지 않도록 통제해야 한다
public class Managers : MonoBehaviour
{
static Managers Instance;
public static Managers GetInstance() { Init(); return Instance; }
void Start()
{
Init();
}
void Update()
{
}
static void Init()
{
if (Instance == null)
{
GameObject go = GameObject.Find("@Managers");
if (go == null)
{
go = new GameObject { name = "@Managers"; }
go.AddComponent<Managers>();
}
}
DontDestroyOnLoad(go);
Instance = go.GetComponent<Managers>();
}
}
추가적으로 아래와 같이 프로퍼티를 활용하면 좀 더 편하게 호출가능하다
public class Managers : MonoBehaviour
{
static Managers s_instance;
public static Managers Instance { get { Init(); return s_instance; } }
void Start()
{
Init();
}
void Update()
{
}
static void Init()
{
if (s_instance == null)
{
GameObject go = GameObject.Find("@Managers");
if (go == null)
{
go = new GameObject { name = "@Managers" };
go.AddComponent<Managers>();
}
DontDestroyOnLoad(go);
s_instance = go.GetComponent<Managers>();
}
}
}
public class Player : MonoBehaviour
{
void Start()
{
Managers mg = Managers.Instance;
}
void Update()
{
}
}
'게임 엔진 - 유니티 > [루키스] 유니티' 카테고리의 다른 글
[유니티 Note] 섹션 3-2 (0) | 2025.06.24 |
---|---|
[유니티 Note] 섹션 3-1 (0) | 2025.06.24 |
[유니티 Note] 섹션 2-2 (0) | 2025.06.23 |
[유니티 Note] 섹션 2-1 (0) | 2025.06.23 |
[유니티 Note] 섹션 1 (1) | 2025.06.23 |