강의 정리

[Unity] [르탄이 카드 뒤집기] 게임 오버 기능, 타임 오버 기능 만들기

lhgenol 2025. 2. 3. 22:22

게임 끝내기(4-7)

게임 오버 기능 만들기

  • 이제 모든 카드의 짝을 맞췄을 때 게임 오버되는 기능을 만들어 보자.
  • '끝'이라는 텍스트가 뜨게 만들어 주고, 그 글자를 클릭했을 때 다시 게임이 실행되도록 하자.
  • TimeTxt 복사해 'EndTxt' 만들기. 세부 설정 하고 off해주자.
  • 게임 오버가 되는 조건: 현재 게임 씬에 남아 있는 카드 오브젝트가 아무것도 없을 때.
    public GameObject endTxt;

    int cardCount = 0;
  • GameManager 스크립트로 가서 endTxt 컴포넌트 추가해 주고, int cardCount 변수도 추가
  • 카드가 세팅됐을 때 이 cardCount에다가 카드의 총 개수를 넣어줄 것. 그리고 카드를 맞췄을 때 파괴되면서 해당 카운트에서 2씩 빼주면 되겠다. 그리고 cardCount값이 0이 됐을 때 게임 오버가 되면 되겠다.
  • cardCount는 결국에 카드를 세팅해주는 곳인 Board에서 넣어줘야 되겠다.
    public int cardCount = 0;
  • public을 붙여주고
    void Start()
    {
        int[] arr = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };
        arr = arr.OrderBy(x => Random.Range(0f, 7f)).ToArray();

        for(int i = 0; i < 16; i++)
        {
            GameObject go = Instantiate(card, this.transform);

            float x = (i % 4) * 1.4f - 2.1f;
            float y = (i / 4) * 1.4f - 3.0f;

            go.transform.position = new Vector2(x, y);
            go.GetComponent<Card>().Setting(arr[i]);
        }

        GameManager.Instance.cardCount = arr.Length;
    }
  • Board 스크립트에서 카드가 다 세팅됐을 때, for문을 다 돌고 끝났을 때 GameManager.Instance.cardCount에다가 배열의 개수만큼 넣어주면 된다.
  • 배열의 개수 구하기: 배열 변수 arr에 .을 찍으면 Length라고 하는 변수가 보임. 이 Length를 통해서 가지고 올 수가 있다.
  • 현재 0부터 15니까 총 배열의 크기는 16. 그럼 이 cardCount에 세팅이 다 되고 나면 16이라는 글자가 들어가겠다.
  • 세팅이 되고 cardCount에는 16이 들어갔다고 가정해보자. 그러면 두 개의 카드가 같아서 파괴했을 때는 cardCount를 2씩 빼주면 되겠다.
    public void Matched()
    {
        if(firstCard.idx == secondCard.idx)
        {
            // 파괴해라.
            firstCard.DestroyCard();
            secondCard.DestroyCard();
            cardCount -= 2;
        }
  • GameManager 스크립트로 가서 DestroyCard 아래에 cardCount -= 2;를 적어주자.
    public void Matched()
    {
        if(firstCard.idx == secondCard.idx)
        {
            // 파괴해라.
            firstCard.DestroyCard();
            secondCard.DestroyCard();
            cardCount -= 2;
            if(cardCount == 0)
            {
                Time.timeScale = 0.0f;
                endTxt.SetActive(true);
            }
        }
  • 그리고 이 카드의 카운트가 0이 됐을 때 timeScale을 0으로 만들어 주고 EndTxt도 켜준다.
    void Start()
    {
        Time.timeScale = 1.0f;
    }
  • 그리고 timeScale을 0으로 만들어주는 로직이 있으니 재실행 했을 때를 생각해서 Start에다 timeScale을 1로 다시 세팅해주는 로직도 넣어주자.
  • GameManager에 EndTxt 변수 넣어주고 플레이 해보면, 카드를 다 맞췄을 때 게임이 멈추며 EndTxt가 뜬다.
  • 이제 이 '끝'을 눌렀을 때 다시 게임이 시작되는 로직도 넣어주자.
  • RetryButton 스크립트 생성
using UnityEngine.SceneManagement;

public class RetryButton : MonoBehaviour
{
    public void Retry()
    {
        SceneManager.LoadScene("MainScene");
    }
}
  • using문에 SceneManagement 추가 후 Retry 함수 생성
  • 그리고 MainScene을 불러와 주는 코드 작성
  • 유니티로 가서 EndTxt에 RetryButton 스크립트와 Button 컴포넌트(+Retry())를 붙여주고 플레이 해보면, '끝'을 눌렀을 때 다시 게임이 시작된다.

게임 난이도 높이기

  • CloseCard의 시간을 조금 짧게 해주자.
    public void CloseCard()
    {
        Invoke("CloseCardInvoke", 0.5f);
    }
  • Card 스크립트에서 시간을 1.0f -> 0.5f로 변경
    public void DestroyCard()
    {
        Invoke("DestroyCardInvoke", 0.5f);
    }
  • 파괴도 1.0f -> 0.5f로 변경
  • 플레이 해보면, 아까보다 빨리 닫히기 때문에 카드를 확인하는 시간이 짧아져서 난이도가 올라갔다. (집중도도 업)

30초가 지나면 게임 끝내기(숙제)

[숙제 설명]

카드 게임인 만큼 속도감 있게 만들어 볼까요?

30초간 플레이하면 게임이 종료되는 시스템을 추가해봅시다!

[필수 숙제]

GameManager.cs 에 접근합니다.
30초가 지나면, 게임을 종료하는 스크립트를 작성합니다.


    float time = 30.0f;
  • time 기본값을 0.0f에서 30.0f로 변경
    void Update()
    {
        time -= Time.deltaTime;
        timeTxt.text = time.ToString("N2");
    }
  • 기존 += Time.deltaTime을 -=로 바꿔주면 시간이 줄어들게 된다.
  • 그리고 이 time이 0이 됐을 때 timeScale이 0이 되면 되겠다.
    void Update()
    {
        time -= Time.deltaTime;
        timeTxt.text = time.ToString("N2");

        if(time < 0.0f)
        {
            endTxt.SetActive(true);
            Time.timeScale = 0.0f;            
        }
    }
  • 만약 time이 0보다 작다면 endTxt를 띄우고 timeScale을 0으로 만든다.

  • 플레이 해보면, 시간이 0이 됐을 때 EndTxt가 뜨며 게임이 멈추는 걸 볼 수 있다.
  • 아 아악
  • 힌트를 보고 코드가 달라서 확인해 보니 전제를 아예 반대로 두고 있었다.
  • 나는 30초 -> 0초 -> 게임 오버로 생각했는데, 숙제는 0초 -> 30초 -> 게임 오버였다.
  • 다시 하자..
    float time = 0.0f;
  • time 기본값 되돌리기
    void Update()
    {
        time += Time.deltaTime;
        timeTxt.text = time.ToString("N2");

        if(time > 30.0f)
        {
            endTxt.SetActive(true);
            Time.timeScale = 0.0f;            
        }
    }
  • -=도 다시 +=로 바꿔주고, time이 30보다 크다면 게임 오버 로직이 작동되게 수정

  • 플레이 해보면, 시간이 30.00이 됐을 때 EndTxt가 뜨며 게임이 멈추는 걸 볼 수 있다.
  • 그래도 두 번 공부했으니 럭키비키다.