미니게임 제작 08
앞으로는 간단한 게임들을 만들어보며 추가적인 기능에 대해 공부를 해보려한다. 간단한 것부터 만들기 시작하여 만든 결과물을 레퍼런스 하여 덩치를 조금씩 키워나가는 과정을 밟아보자. 지식이 많지 않아 부족할 수 있지만, 하는데까지 해보겠다.
현재 구상 하고 있는 것은 예전에 잠깐 화제가 되었던 모바일 게임 매직 서바이벌 과 스팀에서 최근 붐이 일었던 게임 뱀파이어 서바이벌 의 장르를 본딴 생존 서바이벌 슈팅 게임이다.
저번에는 적 개체와 플레이어가 충돌했을 때의 처리를 HP 감소로 바꾸고, Hp를 표시할 UI를 추가하여 표시했다. 오늘은 게임 매니저를 만들어 피격시 발생하는 로직과 게임오버등, 게임의 전반적인 흐름을 제어해볼 것이다.
C# 스크립트를 생성하고, 이름을 GameManager으로 짓는다.
게임 매니저는 일일이 오브젝트에 할당해주고 싶지 않다. 앞서 공부했던 패턴인 싱글턴 패턴을 사용하여 어디서든 접근 가능하도록 할 것이다.
// Private 기본생성자 : sigleton
private GameManager() { }
// 인스턴스 변수 생성 : sigleton
private static GameManager instance = null;
void awake()
{
// 게임 오브젝트 생성 시 객체생성.
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(this.gameObject);
}
}
GameManager에 싱글턴 패턴을 적용시켰다. 이제, 플레이어가 가지고있던 Hp를 옮겨올 것이다. 추가적으로 간단하게 점수와 Hp 감소 메서드에서 이어지는 사망 로직까지 틀을 짜 보겠다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
// 플레이어 Hp
int health = 4;
// 점수
int score = 0;
// hp Bar 객체
public HpBar hpBar;
// Private 기본생성자 : sigleton
private GameManager() { }
// 인스턴스 변수 생성 : sigleton
private static GameManager instance = null;
void Awake()
{
// 게임 오브젝트 생성 시 객체생성.
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(this.gameObject);
}
}
public static GameManager Instance
{
get
{
if (instance == null)
{
return null;
}
return instance;
}
}
void update()
{
scoreUpdate();
if (Input.GetKeyDown(KeyCode.R))
{
restart();
}
}
public void hpDown()
{
if (health > 0)
{
// Hp 감소 및 hpBar 갱신
hpBar.setHp(--health);
}
else
{
// 플레이어의 사망 스크립트 수행(애니메이션 재생)
// 점수 UI 적용
// 다시 시작 UI 적용
}
}
// 점수 갱신 메서드 : 시간에 따라 점수 증가 및 UI 표시
void scoreUpdate()
{
}
// 게임 재시작 메서드 : 플레이어 사망 후 특정 조작을 통해 게임 재시작 : R키
void restart()
{
}
}
전체 스크립트의 틀은 이 정도로 짜면 될 것 같다. 위 스크립트의 비어있는 메서드들을 하나씩 채워나가볼 것이다.
GameManager instance;
void Start()
{
// rigidbody 컴포넌트 가져와 할당하기
playerRigidbody = GetComponent<Rigidbody2D>();
// Animator 컴포넌트 가져와 할당하기
anim = GetComponent<Animator>();
// instance 할당
instance = GameManager.Instance;
}
PlayerControl 스크립트에서는 다음과 같이 게임 매니저의 단일 인스턴스에 접근이 가능하다.
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "Enemy")
{
instance.hpDown();
Destroy(other.gameObject);
}
}
PlayerControl의 충돌 처리 함수는 다음과 같이 변경되었다. 싱글톤을 사용하여 위와 같이 클래스.instance와 같이 프로퍼티로 접근할 수 있다.
이제 충돌할 경우 처리가 게임매니저에서 이루어지게 되었다. 해당 코드를 한 번 살펴보자.
// 플레이어 Hp
int health = 4;
// 점수
int score = 0;
// hp Bar 객체
public HpBar hpBar;
// 플레이어 컨트롤 변수
public PlayerControl playerControl;
// 게임오버 텍스트 변수
public Text gameoverText;
hpBar 감소 및 게임 오버 처리를 위한 변수를 생성하는 부분이다. 각 객체들은 public 으로 설정하여 객체를 할당해 주도록 하자.
public void hpDown()
{
if (health > 1)
{
// Hp 감소 및 hpBar 갱신
hpBar.setHp(--health);
}
else
{
// Hp 감소 및 hpBar 갱신
hpBar.setHp(--health);
// 플레이어의 사망 스크립트 수행(애니메이션 재생)
playerControl.die();
// 게임오버, 점수 UI 적용
gameoverText.gameObject.SetActive(true);
// 다시 시작 UI 적용
}
}
-
Player 게임 오브젝트가 적 개체와 충돌이 일어나 GameManager의 hpDown메서드가 호출된다.
-
hpDown 메서드에서는 health가 1보다 클 경우에는 health가 줄어든다.
-
health가 1인 경우에는 health가 0이 되고, playerControl 스크립트의 die메서드를 수행한다.
-
gameoverText를 활성화시킨다.
Canvas에 Text를 하나 생성한다. 내용은 GameOver으로 하고, 적당한 위치에 설정해두었다.(나중에 꾸며보도록 하자.)
빈 게임 오브젝트를 생성하고, 게임 매니저 스크립트를 집어넣는다. 객체 할당은 위 사진과 같이 한다.
Hp도 정상적으로 줄어들고, Hp가 모두 줄어들었을 때 GameOver 텍스트가 표시되는 것을 볼 수 있다.
아직 문제점은 남아있다. 속도를 0으로 하여 조작을 막았기 때문에 이동 애니메이션이 표시되는 것, 그리고 플레이어의 조작만 막았기 때문에 EnemySpawner에서 Enemy를 계속해서 생성하는 문제가 있다.
다음에는 게임 매니저의 메서드를 구현하고, 위의 문제점을 해결해보겠다.