게임 매니저
👉 전역으로 선언하여 게임 전체를 관리하는 스크립트!
게임 매니저는 '컴포넌트'이므로 딱히 어떠한 오브젝트에 꼭 붙어야 하는 이유는 없지만, 모노비헤이비어를 이용하기 위해 실체는 없지만 Scene에 존재하긴 하는 빈 오브젝트를 만들어서 매니저 스크립트를 컴포넌트로서 붙이고 사용하는 것을 권장한다. 따라서 매니저 스크립트를 붙일 용도의 빈 오브젝트를 만들자.
싱글톤
게임 매니저 스크립트가 붙은 오브젝트를 가져오는 것.
현재 “@Managers” 라는 빈 오브젝트에 게임 매니저로 쓸 Managers 라는 C# 스크립트를 붙여준 상태이다.
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
void Start()
{
GameObject obj = GameObject.Find("@Managers");
Managers mag = obj.GetComponent<Managers>();
}
void Update()
{
}
}
obj 👉 현재 씬에 존재하는 오브젝트(GameObject) 중에서 이름이 “@Managers”인 오브젝트
Find 함수
- GameObject 타입의 함수로서 클래스 함수라 GameObject.Find(String) 식으로 사용 된다. 현재 씬에서 인수와 일치하는 이름을 가진 오브젝트를 찾아 리턴해준다.
- 단, 활성화 되어있는(Active) 오브젝트들 중에서만 찾아준다.
mag 👉 obj 오브젝트의 Managers 컴포넌트를 mag에 담았다.
- C# 스크립트도 컴포넌트다.
- 즉, @Managers 오브젝트의 Managers 스크립트를 참조하게 된다.
[싱글톤 구현하기]
게임 매니저는 게임 전반을 관리하기 때문에 게임 매니저 스크립트는 딱 하나만 필요하므로, static을 이용하여 만들어주고 여러 곳에서 이 동일한 인스턴스를 참조하게 한다.
- 게임 매니저 오브젝트의 스크립트 컴포넌트를 여러 곳에서 공유할 수 있도록 static을 이용하여 만들어 준다.
- 단 하나만 존재하는 이 게임 매니저 컴포넌트를 리턴 받을 수 있는 static 함수를 만들어 둔다. 그렇지만, 다른 곳에서 사용할 수 있도록 public 붙어주어야 한다.
[구현 방법 1]
Managers.cs 👉 게임 매니저로서 동작할 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Managers : MonoBehaviour
{
static Managers Instance; // 유일성이 보장된다.
public static Managers GetInstance() { return Instance; } // 유일한 매니저를 갖고 온다.
void Start()
{
GameObject obj = GameObject.Find("@Managers");
Instance = obj.GetComponent<Managers>(); // Instance에 스크립트를 할당하는 곳
}
void Update()
{
}
}
싱글톤으로 만들 대상은 “@Managers” 오브젝트에 붙어 있는 Managers.cs 스크립트이다. 여러 곳에서 해당 인스턴스에 대해 공유할 수 있도록 static으로 선언한다.
static Managers Instance
여러 곳에서 동일한 인스턴스를 리턴받아 사용할 수 있도록 이 인스턴스를 리턴하는 static public 함수를 만들어준다. 이렇게 할 경우 클래스 함수가 되므로 다른 여러 곳에서 클래스이름.GetInstance() 로 사용할 수 있게 된다.
Instance에 Managers.cs 할당하는 것을 딱 한군데에서만 해주면 단 하나만 존재하는게 보장된다. 👉 Managers.cs에서 할당해준다.
GameObject obj = GameObject.Find("@Managers");
Instance = obj.GetComponent<Managers>(); // Instance에 스크립트를 할당하는 곳
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
void Start()
{
Managers mag = Managers.GetInstance(); // Instance 리턴 받아 사용
}
}
“@Managers” 오브젝트에 붙어 있는 Managers 스크립트가 할당 되어 있는 Instance를 가져와 사용하면 된다. 👉 Managers.GetInstance()
해당 방법의 문제점
1. 만약 @Managers 오브젝트가 없다면 오브젝트가 null이 된다.
👉 이럴 경우 코드를 통하여 @Managers 직접 오브젝트를 만들어 주자.
2. @Managers가 있긴 있어도 Managers.cs 가 붙어있지 않다면 Instance 가 null이 된다.
👉 이럴 경우 마찬가지로 코드를 통하여 @Managers 오브젝트에 Managers.cs 컴포넌트를 붙여준다 😎
[구현 방법 2 - 개선]
Managers.cs 👉 게임 매니저로서 동작할 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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 obj = GameObject.Find("@Managers");
if (obj == null)
{
obj = new GameObject { name = "@Managers" };
obj.AddComponent<Managers>();
}
DontDestroyOnLoad(obj);
Instance = obj.GetComponent<Managers>();
}
}
}
GetInstance(), Start() 두 함수에서 Init()을 호출하는 이유
👉 Managers.cs의 Start() 함수가 실행되기도 전에 다른 스크립트에서 게임 매니저 Instance를 사용해야 할 일이 생긴다면 먼저 그 곳에서 Instance를 만들어 두도록 하기 위하여.
Instance가 아직 없을 경우 인스턴스를 만들어주자. 만약 있을 경우 다음과 같은 과정을 무시하고 지나가면 된다. 👉 if (Instance == null)
- Instance가 단 하나만 존재할 수 있도록 보장이 된다.
- Instance 만들기
- 👉 @Managers라는 오브젝트가 없다면 👉 if (obj == null)
- 👉👉 직접 만들고 Managers.cs 컴포넌트도 붙여주자.
obj = new GameObject { name = "@Managers" };
obj.AddComponent<Managers>();
- DontDestroyOnLoad 함수를 이용해서 “@Managers” 오브젝트가 씬이 변경되도 삭제되지 않고 유지되도록 안전 장치를 걸어주자. 👻
- 마지막으로 Instance에 “@Managers” 오브젝트에 붙어 있는 Managers.cs 가져오기
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
void Start()
{
Managers mag = Managers.GetInstance();
}
}
[구현 방법 3 - 프로퍼티 사용]
Managers.cs 👉 게임 매니저로서 동작할 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Managers : MonoBehaviour
{
static Managers s_instace;
public static Managers Instance
{
get
{
Init();
return s_instace;
}
}
void Start()
{
Init();
}
void Update()
{
}
static void Init()
{
if (s_instace == null)
{
GameObject obj = GameObject.Find("@Managers");
if (obj == null)
{
obj = new GameObject { name = "@Managers" };
obj.AddComponent<Managers>();
}
DontDestroyOnLoad(obj);
s_instace = obj.GetComponent<Managers>();
}
}
}
GetInstance() 함수를 프로퍼티로 변경! 🤠
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
void Start()
{
Managers mag = Managers.Instance;
}
}
변경된 프로퍼티를 이용하여 기존코드에서 Managers mag = Managers.Instance로 변겅해준다. 😑
'공부 > 인프런 - Rookiss' 카테고리의 다른 글
Part 3-3-1. Prefab (프리팹), Resource Manager (0) | 2023.08.17 |
---|---|
Part 3-2-1. Transform (트랜스폼), InputManager (0) | 2023.08.11 |
Part 3. 유니티 엔진 (0) | 2023.08.10 |
Part 2-6-1. A* 길찾기 알고리즘 (0) | 2023.08.10 |
Part 2-5-2. 트리 : 힙 트리, 우선순위 큐 (0) | 2023.08.10 |