Unity 2D 2. Number Wizard

강한친구·2021년 9월 7일
0

Unity Games

목록 보기
2/2

Number wizard

이번 게임은 넘버위자드라고 불리는 게임이다. 이름만 듣고 이게 뭐지 싶겠지만, 범위내의 숫자를 예측하고 그 값을 바탕으로 큰지, 작은지를 판단하여 맞추는 게임이다. 지금 구현한것은 단순하게 하나의 숫자만 가지고 그 숫자에 대해 맞추는 게임이지만,
이 게임을 바탕으로 서로 종류가 다른 4세트의 1~10까지의 숫자카드를 지급하고(트럼프 카드) high low draw를 통해서 다음에 나올 숫자카드가 지금의 숫자카드보다 큰지 작은지 맞추는 게임을 제작해 볼 예정이다.

전체적인 구조

이번 게임의 특징적인 점은 최초로 Scene 전환이라는 기술을 사용했다는 점이다. 이는 추후 설명하도록 하겠다.
원래는 시작화면 게임화면 종료화면 총 3개의 Scene이 필요하지만 이스터에그를 숨겨놓고 4번째 Service Scene을 추가하였다.

Scripts 는 Scene을 불러오기위한 SceneLoader 스크립트와 게임플레이를 위한 NumberWizard 스크립트 2개가 존재하고 나머지 UI및 텍스트 디자인은 무료폰트 및 TextMeshPro를 통해 해결하였다.

NumberWizard.cs

게임운영의 전반을 담당하는 스크립트이다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class NumberWizard : MonoBehaviour {

    [SerializeField] int max;
    [SerializeField] int min;
    [SerializeField] TextMeshProUGUI guessText;

    int guess;

    void Start ()
    {
        StartGame();
	}
	
    void StartGame()
    {
        NextGuess();
    }

    public void OnPressHigher(){
        min = guess+1;
        NextGuess();
        guessText.text = guess.ToString();

    }

    public void OnPressLower() {
        max = guess-1;
        NextGuess();
        guessText.text = guess.ToString();

    }
    void NextGuess()
    {
        guess = Random.Range(min, max+1);
        guessText.text = guess.ToString();
    }

    public void QuitGame() {
        Application.Quit();
    }
}
  1. Startgame()
    게임이 시작할 때 최초로 예측하는 값을 출력하기 위한 메소드이다. 딱 한번실행된다.

  2. NextGuess()
    Guess연산에서 핵심이 되는 메소드이다. Random을 통해 guess의 값을 설정하고 UI에 출력한다
    여기서 특징적인 점은 guessText.text = guess.ToString(); 을 사용했다는것인데 이는 UI Text가 Int, Float형 같은 숫자는 출력하지 못하고 오로지 String만 출력 가능하다는점에서 이렇게 작성되었다.

  3. PressOnHigher, Lower()
    Higer, Lower 버튼이 눌러졌을 때, 그 버튼에 맞는 기능을 하도록 작성된 코드이다. Higher의 경우 min을 guess+1로 올리고, Lower의 경우 max를 guess -1 로 바꾼다. +1 ,-1의 이유는 이미 그 값은 아니라고 판명되었기에 중복출력을 피하기 위함이다.

게임의 플레이적인 부분을 담당하는 코드는 단순하고 간단하다.

SceneLoader.cs

우선 SceneLoader를 이용하려면 Sceneloading이 어떤식으로 작동하는지 알아야한다. File - Build Setting에 들어가면 이런식으로 Scene에 번호를 지정하여 저장해 둘 수 있는 기능이 있다. 각 Scene의 작동순서별로 번호가 붙어있으며, 이에 맞춰서 코드를 작성하면 다음 Scene으로 넘어가고 마지막 Scene에서는 최초의 Scene으로 돌아가는 별도의 코드를 작성하는식으로 운영된다

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour{

    public void LoadNextScene() {
        int currentSceneIdx = SceneManager.GetActiveScene().buildIndex;
        SceneManager.LoadScene(currentSceneIdx + 1);
    }

    public void LoadStartScene() {
         SceneManager.LoadScene(0);
    }

    public void hiddenScene() {
        SceneManager.LoadScene(3);
    }
}

우선 UnityEngine의 SceneManagement를 호출해야한다

  • 자바의 경우 import java.util.Scanner 이런식으로 호출하거나 혹은 import java.util.* 을 통해 java.util 아래에 있는 모든 기능을 호출 할 수 있다. 이에 처음에는 UnityEngine을 불렀는데 왜 또 SceneManagement를 호출 하는지 의문을 가질 수 있다. 하지만 CS에서는 UnityEngine을 불렀다고 하위 모든 기능을 불러오는것이 아니기에 이런식으로 따로 작성하여야한다. 이를 잘 알아두면 편할것이다.

그 후 SceneManagement에 있는 기능들을 통해 현재 Scene의 Idx를 따오고 [SceneManager.GetActiveScene().buildIndex] 다음 Scene으로 가는 코드를 LoadScene을 통해 작성하면 된다. [SceneManager.LoadScene(currentSceneIdx + 1)]
이러면 끝이다? 일까

잠깐! 만약 마지막 장면이면 어떻게 되는걸까? 기존의 코드대로라면 Scene Idx는 하나 늘어나고 그대로 없는 Scene으로 돌입하여 오류를 호출하게 될 것이다.

그래서 우리는 마지막 Scene에서 사용할 LoadStartScene 메소드를 따로 작성하였다.

LoadStartScene 메소드를 통해 우리는 Scene을 강제로 0번으로 돌려보낼 수 있다.

  • hiddenScene 메소드는 숨겨진 Service Scene으로 가기 위한 별도의 메소드이다. 하지만 Scene은 순서대로 되어있어서 이 경우에는 저런 기능 없이 그냥 LoadNextScene을 사용하여도 무방하다.

GameObject에 적용

그래서 작성한 이 코드들은 도대체 어떻게 사용하는것일까?

그 비밀은 GameObject에 있다.

Starting Menu의 세부적인 구조이다. 자세히 보면 SceneLoader라는 Object가 하나 있다. 이게 무엇일까?

바로 Create Empty에서 작성된 Empty Object를 이름을 바꿔주고 그 안에 스크립트를 붙여넣은것이다.

이런식으로 Object안에 Script를 할당할 수 있고 이제 이 Object를 버튼에 할당하고 OnClick에 맞춰서 버튼작동에 걸맞는 메소드를 호출하여 작동하도록 설정하면 된다. 만약 Script를 직접 넣게된다면 OnClick에서 메소드를 고를 수 없게 된다.

사실 이 작성에는 오류가 하나 있다. 바로 Quit의 기능을 NumberWizard에 구현하여 SceneLoader가 NumberWizard, SceneLoader 두가지의 스크립트를 받고있다는 점이다. 물론 게임을 실행하고 작동하게 하는것에는 큰 문제가 없겠지만, 불필요한 기능이 불필요한 Scene에 들어가게 된 것이다. 따라서 Quit 코드는 SceneLoader에만 넣고 StartScene의 Object에는 SceneLoader만 가지고 있는것이 합리적이라 할 수 있다.

제대로 할당하게 된다면 이런식으로 작성된다

이렇게 GameObject에 스크립트를 할당하고 이를 Onclick()에 넣어주는것으로 버튼이 눌러졌을경우 어떠한 일을 하게 될 지 설정할 수 있다.

마치며

이번 게임은 간단하지만 기본기를 많이 다질 수 있는 시간이 되었다. 특히 GameObject 할당과 UI관리면에선 많은 도움이 되었다.
이 지식을 바탕으로 다음 목표인 Block Breaker (벽돌깨기)와 Hi-Lo 게임을 구현해 볼 생각이다. 뭘 먼저 하게 될지는 아직 모르겠다.

0개의 댓글