오늘은 전체 게임들을 관리하는 싱글톤 매니저들의 구조를 설계하고 구현했다!
Scene들을 관리하기 위해 SceneManagerEx를 만들었다.
CurrentScene에 현재 Scene의 정보를 담는다.
private Scenes _curSceneType = Scenes.Unknown; // 현재 Scene
private Scenes _nextSceneType = Scenes.Unknown; // 현재 Scene이 LoadingScene일 경우 다음에 호출 될 Scene
public Scenes CurrentSceneType
{
get
{
if (_curSceneType != Scenes.Unknown) return _curSceneType;
return CurrentScene.SceneType;
}
set
{
_curSceneType = value;
}
}
public Scenes NextSceneType
{
get
{
return _nextSceneType;
}
set
{
_nextSceneType = value;
}
}
// 현재 Scene 정보
public BaseScene CurrentScene
{
get
{
return GameObject.Find("@Scene").GetComponent<BaseScene>();
}
}
LoadScene
public void LoadScene(Scenes sceneType, Scenes nextSceneType = Scenes.Unknown)
{
CurrentScene.Clear();
_curSceneType = sceneType;
if (_curSceneType == Scenes.LoadingScene) _nextSceneType = nextSceneType;
SceneManager.LoadScene(_curSceneType.ToString());
}
```cs
SceneManagerEx.Instance.LoadScene(Scenes.MainScene);
```
Scenes
public enum Scenes
{
Unknown,
StartScene,
MainScene,
LoadingScene,
}
BaseScene
public class StartScene : BaseScene
{
protected override bool Init()
{
if (!base.Init()) return false;
SceneType = Scenes.DevelopGameScene;
// StartScene이 로드 되었을 때 필요한 동작 정의
return true;
}
public override void Clear()
{
// StartScene에서 다른 Scene으로 전환되기 전 필요한 동작 정의
}
}
세팅하기
우리 프로젝트에서는 각 미니 게임마다 해당 게임을 관리할 게임 매니저가 있고, 이들을 통합해서 관리할 매니저가 필요했다.
그래서 이 역할을 GameManager가 맡는 방식으로 구현했다!
GameManager는 각 미니 게임을 관리하는 미니 게임의 매니저들을 Dictionary에 담아 관리한다.
// 각 미니 게임들을 관리하는 미니 게임 매니저들을 저장하는 딕셔너리
private Dictionary<string, MonoBehaviour> _miniGameManagers = new Dictionary<string, MonoBehaviour>();
사용하기
GameManager.Instance.GetMiniGameManager<DevelopGameManager>();
public class Graph : MonoBehaviour
{
private DevelopGameManager _developGameManager;
private void Awake()
{
nodeList = GetComponentsInChildren<Node>();
// 게임 매니저를 통해서 미니 게임을 관리할 매니저 호출
_developGameManager = GameManager.Instance.GetMiniGameManager<DevelopGameManager>();
}
}
UI 컴포넌트들을 Dictionary에 저장해서 관리한다.
// Resources/Prefabs/UI 안의 UI 컴포넌트 프리팹들을 저장하는 딕셔너리
Dictionary<string, UIBase> uiDic = new Dictionary<string, UIBase>();
세팅하기
public class DevelopGameManager : MonoBehaviour
{
private UI_Popup _uiPopup;
private UI_GameEndPopup _uiGameEndPopup;
private UI_DevelopGameScene _uiDevelopGameScene;
private void Start()
{
_uiPopup = UIManager.Instance.GetUIComponent<UI_Popup>();
_uiGameEndPopup = UIManager.Instance.GetUIComponent<UI_GameEndPopup>();
_uiDevelopGameScene = UIManager.Instance.GetUIComponent<UI_DevelopGameScene>();
_uiPopup.ShowPopup(Strings.PopupContent.DEVELOP_GAME_NOTIFICATION, Strings.PopupButtons.OK, null);
}
}
Resources/Sprites 폴더 안의 이미지 리소스들을 Dictionary에 담아 관리한다.
public Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();
사용 방법
Sprite sprite = ResourceManager.Instance.LoadSprite("이미지 소스 이름");
Resources/Sounds 폴더 안의 사운드 리소스들을 Dictionary에 담아 관리한다.
public Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();
Play와 Stop
public void Play(string audioClipName, AudioType audioType = AudioType.EFFECT, float volume = 1.0f)
{
AudioClip audioClip = LoadAudioClip(audioClipName);
switch(audioType)
{
case AudioType.BGM:
if (_audioSource.isPlaying) _audioSource.Stop();
_audioSource.volume = volume;
_audioSource.clip = audioClip;
_audioSource.loop = true;
_audioSource.Play();
break;
case AudioType.EFFECT:
_audioSource.volume = volume;
_audioSource.PlayOneShot(audioClip);
break;
}
}
public void Stop()
{
if (_audioSource.isPlaying) _audioSource.Stop();
}
사용 방법
// 배경음악 재생
SoundManager.Instance.Play("오디오 클립 이름", AudioType.BGM);
// 효과음 재생
SoundManager.Instance.Play("오디오 클립 이름");
// volume 조절이 필요한 경우
SoundManager.Instance.Play("오디오 클립 이름",
AudioType.BGM, 0.5f);
// 음악 정지
SoundManager.Instance.Stop();
프로젝트를 진행할 때마다 고민이었던 Manager 구조를 이번에 꽤 만족스럽게 구현했다!
아직 더 보완할 점들과 추가하고 싶은 것들이 많기 때문에 팀 프로젝트가 끝난 이후에 더 디벨롭 할 예정이다 히히 'ㅅ'
끗~~~