게임 개발 로그
미니게임: 미로 숨바꼭질 본문
0. 구현
Managers
- GameManager
- EventBusManager
- LoadingSceneManager
- SoundManager
GameManager
게임 진행 중인지 판단 및 점수/시간 기록, 게임 오버 판단 등을 담당함.
public class GameManager : SingleTon<GameManager>
{
public bool bGameOver = false;
public int score = 0;
public int enemyScore = 0;
public float time = 60;
public bool isPlaying = true;
private void Update()
{
if (isPlaying)
{
time -= Time.deltaTime;
if (time < 0)
{
bGameOver = true;
time = 0;
isPlaying = false;
EventBusManager.Publish(EventBusType.Timeout);
}
}
}
public void GameOver()
{
Debug.Log("GameOver");
isPlaying = false;
bGameOver = true;
EventBusManager.Publish(EventBusType.Gameover);
}
public void GameReset()
{
score = 0;
enemyScore = 0;
bGameOver = false;
isPlaying = true;
time = 90;
EventBusManager.Clear();
}
}
EventBusManager
이벤트 발생 시 구독자에게 이벤트 발생 여부를 전달해 주는 역할이다. 플레이어가 데미지를 받았을 때 HUD와 UI에 사용하기 위해 PlayerDamaged 이벤트를, GameOver와 Timeout 등의 이벤트를 처리하기 위해 세 가지 타입을 사용하고 있다.
public enum EventBusType
{
PlayerDamaged,
Gameover,
Timeout,
Max
}
public class EventBusManager : MonoBehaviour
{
private static readonly IDictionary<EventBusType, UnityEvent>
Events = new Dictionary<EventBusType, UnityEvent>();
public static void Subscribe(EventBusType eventType, UnityAction listener)
{
UnityEvent thisEvent;
if (Events.TryGetValue(eventType, out thisEvent))
{
thisEvent.AddListener(listener);
}
else
{
thisEvent = new UnityEvent();
thisEvent.AddListener(listener);
Events.Add(eventType, thisEvent);
}
}
public static void UnSubscribe(EventBusType eventType, UnityAction listener)
{
UnityEvent thisEvent;
if (Events.TryGetValue(eventType, out thisEvent))
{
thisEvent.RemoveListener(listener);
}
}
public static void Publish(EventBusType eventType)
{
UnityEvent thisEvent;
if (Events.TryGetValue(eventType, out thisEvent))
{
thisEvent.Invoke();
}
}
public static void Clear()
{
Events.Clear();
}
}
LoadingSceneManager
씬을 넘어가는 Manager인데 Loading하는 씬을 포함하고 싶어서 변형을 줬다. 오브젝트가 많지 않은 씬이라 넘어갈 때 너무 순식간에 넘어가서 fakeTime을 추가하여 천천히 로딩 프로그레스바가 올라가도록 했다. LoadingSceneManager.Instance.LoadSceneWithFadeEffect("SceneName")으로 로딩씬&씬전환을 사용할 수 있는데, 씬 전환 전에 먼저 FadeOut, In 효과를 준다. Fade 이펙트가 완전히 까맣게 되면 로딩씬으로 넘어가고, 로딩 씬에서 Next Scene을 로드하면서 로딩된 정도에 따라 프로그레스바를 변경시킨다. 로드가 완료되면 다음 씬으로 넘어가면서 또다시 FadeIn/Out 효과를 준다.
public class LoadingSceneManager : SingleTon<LoadingSceneManager>
{
private const float fakeTime = 5.0f;
public string nextScene;
public float fadeTime = 1.0f;
public GameObject uiPrefab;
public GameObject uiObj;
private LoadingUI loadingUi;
private Image image;
protected override void Awake()
{
base.Awake();
if (image == null)
{
Canvas canvas = gameObject.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
gameObject.AddComponent<CanvasScaler>();
gameObject.AddComponent<GraphicRaycaster>();
image = gameObject.AddComponent<Image>();
image.color = Color.black;
Color temp = image.color;
temp.a = 0;
image.color = temp;
uiPrefab = Resources.Load("Prefabs\\MazeGame\\LoadingUI") as GameObject;
}
}
public void LoadSceneWithFadeEffect(string nextScene)
{
this.nextScene = nextScene;
StartCoroutine(LoadingSceneWithFadeEffect());
}
IEnumerator LoadingSceneWithFadeEffect()
{
Color temp = image.color;
while (temp.a <= 0.99)
{
temp.a += Time.deltaTime;
image.color = temp;
yield return null;
}
temp.a = 1;
image.color = temp;
SceneManager.LoadScene("LoadingScene");
while (temp.a >= 0.01)
{
temp.a -= Time.deltaTime;
image.color = temp;
yield return null;
}
temp.a = 0;
LoadScene(nextScene);
uiObj = Instantiate(uiPrefab);
loadingUi = uiObj.GetComponent<LoadingUI>();
}
public void LoadScene(string sceneName)
{
nextScene = sceneName;
StartCoroutine(LoadScene());
}
IEnumerator LoadScene()
{
AsyncOperation op = SceneManager.LoadSceneAsync(nextScene);
op.allowSceneActivation = false;
float timer = 0.0f;
while (!op.isDone)
{
yield return null;
timer += Time.deltaTime;
if (op.progress + timer < 0.9f * fakeTime)
{
loadingUi.SetProgress(Mathf.Lerp(loadingUi.GetProgress(), (op.progress + timer) / fakeTime, timer / fakeTime));
}
else
{
loadingUi.SetProgress(Mathf.Lerp(loadingUi.GetProgress(), 1f, timer));
if (loadingUi.GetProgress() == 1.0f)
{
if (nextScene == "GameScene")
GameManager.Instance.isPlaying = true;
StartCoroutine(ActiveSceneWithFadeEffect(op));
yield break;
}
}
}
}
IEnumerator ActiveSceneWithFadeEffect(AsyncOperation op)
{
Color temp = image.color;
while (temp.a <= 0.99)
{
temp.a += Time.deltaTime;
image.color = temp;
yield return null;
}
temp.a = 1;
image.color = temp;
op.allowSceneActivation = true;
loadingUi = null;
while (temp.a >= 0.01)
{
temp.a -= Time.deltaTime;
image.color = temp;
yield return null;
}
temp.a = 0;
}
}
'게임 개발 > 미니게임' 카테고리의 다른 글
미니게임: Carrot Flight (0) | 2024.11.21 |
---|---|
Flappy Brid (1) | 2024.11.12 |