게임 매니저는 게임 로직을 관리하고 승리 조건을 판별하는 중앙 제어 시스템이다. 여기에서는 C# 스크립트로 GameManager
클래스를 만든다.
먼저, 게임의 승리 조건을 판별하기 위해 사용되는 ItemBox
클래스에 isOveraped 변수를 추가한다.
public class ItemBox : MonoBehaviour
{
public bool isOveraped = false; // 충돌 여부
private Renderer myRenderer;
public Color touchColor;
private Color originalColor;
// 나머지 코드...
]
다음은 GameManager
클래스다. 이 클래스는 ItemBox
오브젝트의 isOveraped
값을 모니터링하여 모든 상자가 목표 지점에 도달했는지 판단한다.
public class GameManager : MonoBehaviour
{
public ItemBox[] itemBoxes;
public bool isGameOver;
void Start()
{
isGameOver = false;
}
void Update()
{
if(isGameOver == true)
{
return;
}
int count = 0;
for(int i = 0; i < 3; i++)
{
if(itemBoxes[i].isOveraped == true)
{
count++;
}
}
if(count >= 3)
{
Debug.Log("게임 승리!");
isGameOver = true;
}
}
}
승리 조건을 만족하면 플레이어에게 승리 메시지를 표시해야 한다. 아래의 단계에서는 승리 UI를 만드는 방법을 설명한다.
GameManager
클래스의 Update
메서드를 수정하여 승리 조건이 충족되면 승리 UI를 활성화하도록 한다.
public class GameManager : MonoBehaviour
{
public GameObject winUI; // 승리 UI 참조
// 나머지 코드...
void Update()
{
// 기존 코드...
if(count >= 3)
{
Debug.Log("게임 승리!");
isGameOver = true;
winUI.SetActive(true); // 승리 UI 활성화
}
}
}
위의 코드와 함께, Unity Editor에서 "Win UI" 오브젝트를 GameManager
의 "Win UI" 필드에 드래그 앤 드롭해야 한다.
이렇게 하면, 게임 매니저와 승리 조건의 구현이 완료되고, 승리 UI가 게임 승리 시 활성화된다.
사용자가 스페이스바를 눌렀을 때 게임을 재시작할 수 있게 구현하기
우선, UnityEngine.SceneManagement
네임스페이스를 추가해야 한다. 이 네임스페이스 안에는 장면(Scene) 관리와 관련된 여러 클래스와 메서드가 포함되어 있다. 여기서는 장면을 로드하는 SceneManager.LoadScene
메서드를 사용한다.
using UnityEngine;
using UnityEngine.SceneManagement; // 이 부분은 Scene 관리를 위한 네임스페이스
public class GameManager : MonoBehaviour
{
// ... 다른 변수 선언
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) // 스페이스바를 눌렀을 때의 이벤트 감지
{
SceneManager.LoadScene(0); // 현재 장면(인덱스 0)을 다시 로드
}
// ... 나머지 코드
}
}
이렇게 하면 스페이스바를 눌렀을 때, 현재 장면이 다시 로드되어 게임이 재시작된다. 재시작 시 모든 오브젝트와 변수가 초기 상태로 리셋되므로 게임을 처음부터 다시 시작할 수 있다.
게임에 배경 음악을 추가하려면, 오디오 소스 컴포넌트를 사용하고 원하는 음악 파일을 설정해야 한다.
이렇게 하면 배경 음악이 게임 시작시 자동으로 재생되며, 무한 반복된다.
이 섹션에서는 게임이 끝났을 때 플레이어의 움직임을 어떻게 제어하는지에 대해 설명한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public GameManager gameManager; // GameManager의 참조를 위해 변수를 선언. 게임 상태를 확인하기 위해 사용한다.
// ... 다른 변수 선언
void Update()
{
if (gameManager.isGameOver == true) // GameManager의 `isGameOver` 변수가 true일 경우, 플레이어의 움직임 코드 실행을 중단한다.
{
return; // 이후 코드 실행을 중단, 움직임 제어 안 함
}
// ... 플레이어 움직임 처리 코드
}
}
이렇게 하면 게임이 끝나면 플레이어의 움직임을 제어하지 않아 움직이지 않게 된다.
게임 개발이 완료되면, 마지막 단계는 빌드(Build)와 실행(Run)이다. 이 과정은 Unity에서 쉽게 수행할 수 있다.
이 과정을 통해 선택된 플랫폼에 맞는 실행 파일이 생성되며, 자동으로 게임이 실행된다. 빌드 설정에서 다양한 옵션을 변경하여 게임의 해상도, 아이콘 등을 설정할 수도 있다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public GameObject winUI; // 게임 승리시 활성화할 UI 게임 오브젝트
public ItemBox[] itemBoxes; // ItemBox 배열 선언
public Boolean isGameover = false; // 게임 오버 상태 변수
void Start()
{
isGameover = false; // 게임 오버 상태를 게임 중으로 변경
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
//SceneManager.LoadScene(0); // 씬의 순번으로 로드
SceneManager.LoadScene("Sokovan/Scenes/Main"); // 씬의 이름으로 로드
}
if (isGameover) return; // 게임 오버 상태라면 업데이트를 진행하지 않음
int count = 0; // ItemBox 중에서 충돌한 ItemBox의 개수를 저장할 변수
for(int i = 0; i < 3; i++) // 3개의 ItemBox를 모두 확인
{
if (itemBoxes[i].isOveraped) count++; // 만약 ItemBox가 충돌했다면 count를 1 증가
}
if(count >= 3) // 만약 충돌한 ItemBox의 개수가 3개 이상이라면
{
Debug.Log("게임 승리");
winUI.SetActive(true); // 게임 승리 UI 활성화
isGameover = true; // 게임 오버 상태를 게임 승리로 변경
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemBox : MonoBehaviour
{
public bool isOveraped = false; // 아이템 박스와 충돌했는지 여부를 저장할 변수
private Renderer myRenderer; // ItemBox의 Renderer 컴포넌트를 참조
public Color touchColor; // 충돌시 바뀔 색을 참조할 변수
void Start()
{
myRenderer = GetComponent<Renderer>(); // Renderer 컴포넌트를 가져옴
}
void Update()
{
}
// 트리거 콜라이더와 충돌했을 때 자동으로 실행
private void OnTriggerEnter(Collider other)
{
if (other.tag == "EndPoint") // 태그가 "EndPoint"일 경우
{
isOveraped = true; // isOveraped를 true로 변경
myRenderer.material.color = touchColor; // 색을 touchColor로 변경
}
}
// 트리거 콜라이더와 충돌이 끝났을 때 자동으로 실행
private void OnTriggerExit(Collider other)
{
if (other.tag == "EndPoint") // 태그가 "EndPoint"일 경우
{
isOveraped = false; // isOveraped를 false로 변경
myRenderer.material.color = Color.white; // 색을 흰색으로 변경
}
}
// 트리거 콜라이더와 충돌하고 있는 동안 계속 실행
private void OnTriggerStay(Collider other)
{
if (other.tag == "EndPoint") // 태그가 "EndPoint"일 경우
{
isOveraped = true; // isOveraped를 true로 변경
myRenderer.material.color = touchColor; // 색을 touchColor로 변경
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public GameManager gameManager; // 게임 매니저
// 플레이어의 이동 속도
public float speed = 10f;
// 플레이어의 리지드바디 컴포넌트
Rigidbody playerRigidbody;
// 게임이 시작될 때 한 번만 호출되는 함수 -> 초기화
void Start()
{
// GetComponent<타입>() : 타입에 해당하는 컴포넌트를 찾아서 반환
playerRigidbody = GetComponent<Rigidbody>();
}
// 매 프레임마다 호출되는 함수 -> 유저 입력을 받아서 처리
void Update()
{
if (gameManager.isGameover) return; // 게임 오버 상태라면 업데이트를 진행하지 않음
// GetAxis() : 키보드 입력을 받아서 -1 ~ 1 사이의 값을 반환
float inpuitX = Input.GetAxis("Horizontal"); // 조이스틱 대응 가능
float inputZ = Input.GetAxis("Vertical");
float fallSpeed = playerRigidbody.velocity.y; // 중력에 의해 떨어지는 속도를 유지시키기 위해
// 방향 * 속도 = 속도 벡터
Vector3 velocity = new Vector3(inpuitX, 0f, inputZ);
velocity = velocity * speed; // 방향 * 속도
velocity.y = fallSpeed; // 중력에 의해 떨어지는 속도를 유지시키기 위해
// 리지드바디의 속도를 velocity로 변경
playerRigidbody.velocity = velocity;
}
}