강의 정리
[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가 뜨며 게임이 멈추는 걸 볼 수 있다.
- 그래도 두 번 공부했으니 럭키비키다.