GameDevelop/Unity기초쌓기

[Unity] 게임종료 로직

도도돋치 2025. 4. 6. 18:58
Contents 접기
728x90

싱글톤 개념

📌 리마인드 - 싱글톤이란? [나는 딱 하나야] 라고 할 수 있게 세팅해두는 것 
(그래야 다른 곳에서 나를 부를 수 있다)
public static GameManager Instance;

public void Awake()
{
	if(Instance == null)
	{
		Instance = this;
	}
}
Instance == null 이란?
null 은 비어있다는 뜻

변수는 데이터/값을 담아 놓는 박스라고 했는데, 이 변수(박스)가 비어 있을 때
Instance = this를 해주겠다는 뜻

 

싱글톤 생성

게임 진행에 필요한 사항 -> GameManager에 생성

풍선과 충돌이 일어났을 때 게임 매니저에 있는 게임 종료 로직을 꺼내 오도록 한다.

 

먼저 GameManger를 싱글톤으로 만들어 준다. 

GameManger Script
 //너 하나야 표시해주기 위해 static이라는 키워드를 사용 
public static GameManager Instance;
//Start보다 빨리 호출되는 Awake
private void Awake()
{
    if(Instance == null)
    {
        Instance = this;
    }
}

 

게임오버 로직

GameManger Script

밖에서 꺼낼 예정이니까 밖에서 꺼낼 수 있게 public으로 만들어줌

필요한 기능은 2가지 1️⃣ 게임을 멈춰주는 기능 2️⃣ 게임오버 시 EndPanel를 띄워주는 기능

public void GameOver()
{
    //게임을 멈춰주는 기능 -> time으로 접근
    Time.timeScale = 0.0f;
}
public GameObject endPanel; //endPanel에 접근하기 위한 변수

public void GameOver()
{
    //게임을 멈춰주는 기능 -> time으로 접근
    Time.timeScale = 0.0f;
    //게임over시 EndPanel을 띄워주는 기능
    endPanel.SetActive(true);
}

SetActive(true)는 Inspector창에 있는 게임 오브젝트 이름 옆에 있는 체크박스가 체크 되어있다는 뜻(endPanel이 보인다는 뜻)

 

GameManger의 EndPanel에 EndPanel드래그 앤 드롭해준다.

 

현재 점수 띄우기

게임이 종료됐을 때 현재 게임 오버시 멈춘 시간을 현재 점수로 보여주어야 한다.

즉, 시간 값을 현재 스코어에다가 넣어줘야 한다. (현재스코어-> NowScore에 넣어줘야함)

GameManger Script
public Text nowScore;   //현재시간(이번게임점수)를 담기위한 값
public void GameOver()
{
    Time.timeScale = 0.0f;
    nowScore.text = time.ToString("N2");  //nowScore의 text값에 time값을 넣어줌 
    endPanel.SetActive(true);
}

 

충돌시 GameManger의 GameOver함수 호출하기

square이 충돌한게 balloon이라는 것을 알 수 있게끔 ballon에 Player 태그를 추가한다.

Square Script

충돌하는 거 확인 -> onCollision 

onCollisionEnter2D치고 엔터 치면 함수 자동 완성이 된다. 

private void OnCollisionEnter2D(Collision2D collision)
{
    
}

Square에 충돌된 것의 정보는 이 함수의 매개변수 collision에 들어가게 된다. 

collision에 있는 충돌된 물체 정보들 중에서 우리는 태그값을 가져와야 한다.

private void OnCollisionEnter2D(Collision2D collision)
{
    if(collision.gameObject.CompareTag("Player"))
    {
        //Instance로 접근해야함
        GameManager.Instance.GameOver();
    }
}

 

다시 유니티로 돌아가서 GameManger의 NowScore에 NowScore오브젝트를 드래그 앤 드롭으로 넣어준다.  

이렇게 하면 시간값이 현재 점수에 잘 들어가는 것을 확인 할 수 있다.


소수점 단위에서 값이 1,2정도 달라지는 현상이 있다. 이 현상을 막아보자.

GameManager Script
bool isplay = true;

GameOver시 isPlay를 false로 바꿔주고, 

public void GameOver()
{
    isPlay = false; //게임 오버시 isPlay를 false값으로 바꿔줌
    Time.timeScale = 0.0f;
    nowScore.text = time.ToString("N2");
    endPanel.SetActive(true);
}

update부분에서 isPlay가 true일 경우에만 시간을 더해주도록 변경한다.

 void Update()
{
    if(isPlay)
    {
        time += Time.deltaTime;
        timeTxt.text = time.ToString("N2"); //화면상의 text값에 time을 string(문자열)으로 변환해서 넣어주고 소수점 2번째 지리까지 표시 
    }
}

 

Retry() 생성

RetryButton Script를 추가하고 RetryButton 오브젝트에 드래그 앤 드롭으로 스크립트를 붙여준다.

RetryButton Script

 

* 사용하지 않는 Start, Update는 지워주는 습관이 좋다.

Retry로직이 실행이 되면 우리는 MainScene을 다시 로드해 주는 기능을 만들어 줄 것이다.

Scene을 로드하는 기능 -> Scenemanager

만약 SceneManger이 바로 만들어지지 않는다면
using UnityEngine.SceneManagement;가 있는지 확인
public class RetryButton : MonoBehaviour
{
    public void Retry()
    {
        SceneManager.LoadScene("MainScene");
    }
}

 

Hierarchy의 RetryBtn의 OnClick의 +버튼을 누른 후 RetryBtn을 추가하고,

NoFucntion에서 RetryButton>Retry()함수를 선택한다.

이렇게 하면 클릭이 되었을 때 이 Retry함수가 실행이 된다. 

 

게임 재시작

하지만 이렇게 하면 재시작은 되지만, 게임이 멈춰있게 된다. 

그렇다면 GameManager에서 timeScale을 다시 1로 바꿔주어야 한다. 

GameManager Script
void Start()
{
    Time.timeScale = 1.0f;
    InvokeRepeating("MakeSquare", 0f, 1f);   // 함수이름, 언제실행시킬건지(바로 실행시 0f), 얼마만큼 자주 실행시킬건지
}

 

 

결과화면

 

 

 

728x90