
미니게임에 입장하면 Click To Start 문구가 표시되고, 게임이 종료되면 Game Over 문구와 함께 재시작 버튼, 메인 이동 버튼이 보이게 만들었다.

그런데 게임 오버 시 위 이미지처럼 시작 시에만 표시돼야 하는 Click To Start가 함께 뜨는 문제가 발생했다.
관련 코드를 보면 이렇다.
<UI 스크립트>
// 게임 오버 시 재시작 안내 문구를 표시하는 함수
public void SetStart(bool show)
{
startText.gameObject.SetActive(show); // 시작 텍스트 활성화
}
// 게임 오버 시 게임 오버 문구 및 버튼 표시하는 함수
public void SetGameOverUI()
{
startText.gameObject.SetActive(false); // 시작 문구 숨기기
gameOverText.gameObject.SetActive(true); // 게임 오버 문구 활성화
restartButton.gameObject.SetActive(true); // 재시작 버튼 활성화
mainButton.gameObject.SetActive(true); // 메인 버튼 활성화
}
// 재시작 버튼 클릭 시 호출되는 함수
private void OnRestartClicked()
{
GameManager.Instance.RestartGame();
}
// 메인 버튼 클릭 시 호출되는 함수
private void OnMainClicked()
{
GameManager.Instance.GoToMenu();
}
<Game Manager 스크립트>
// 미니게임 입장 시 보여줄 세팅
private void Start()
{
Time.timeScale = 0; // 게임을 멈춤
uiManager.UpdateScore(0); // 게임 시작 시 점수를 0으로 설정하고 UI에 반영
uiManager.SetStart(true); // UI 매니저의 재시작 버튼 활성화
}
private void Update()
{
if (!gameStarted) // 아직 게임이 시작되지 않았다면
{
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
{
StartGame(); // 키 입력 시 게임 시작
}
}
}
// 게임 실행 시
private void StartGame()
{
gameStarted = true;
uiManager.SetStart(false); // "Click to Start" 문구 숨기기
Time.timeScale = 1; // 게임 시작
}
public void GameOver()
{
uiManager.SetStart(false); // 게임 오버 시 "Click to Start" 문구 숨기기
uiManager.SetGameOverUI(); // UI 매니저의 재시작 버튼 활성화
}
public void RestartGame()
{
// 현재 활성화된 씬(게임 씬)을 다시 로드하여 게임을 재시작
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void GoToMenu()
{
SceneManager.LoadScene("SampleScene"); // 메인 씬으로 이동
}
}
SetStart(bool show)
미니게임 씬 입장 시에 startText를 보여주고, 게임이 시작되면 해당 문구를 꺼주기 위해 bool로 세팅했다.
처음엔 여기에 bool값을 잘못 입력했나 싶어서 고쳐봤는데 이 문제는 아니었다.
// 게임 오버 시 게임 오버 문구 및 버튼 표시하는 함수
public void SetGameOverUI()
{
startText.gameObject.SetActive(false); // 시작 문구 숨기기
restartText.gameObject.SetActive(true); // 게임 오버 문구 활성화
restartButton.gameObject.SetActive(true); // 재시작 버튼 활성화
mainButton.gameObject.SetActive(true); // 메인 버튼 활성화
}
SetGameOverUI()
게임 오버 시에는 startText를 끄도록 설정해 줬는데 계속해서 켜지는 상황..
GameManager.cs 에서 게임 오버 시 해당 SetStart를 꺼줘도 봤는데 변화는 없었다.
코드상으로는 문제가 없어 보여 디버그 로그를 찍어보니 게임 오버 시 Start가 게임 종료 시 두 번씩 호출되고 있었다.
그외에도 GameManager에 등록해 놓은 메서드들이 두 번, 세 번씩 실행됨
문제는 싱글톤화 한 GameManager.cs를 미니게임 씬 내 Canvas나 Button등 여러 곳에 중복으로 붙여놓아서 또다시 함수들이 호출된 것.
싱글톤 패턴을 사용한 스크립트는 반드시 하나만 유지되어야 하는데 그걸 지키지 않아 생긴 문제였다.
미니게임 씬 내 RestartButton, MainButton, Canvas에 첨부한 GameManager 스크립트를 모두 제거하고 GameManager 오브젝트에만 스크립트 부여하니 해결되었다.
추가적으로 버튼 기능을 구현하려 할 때, 아무 생각 없이 버튼 안에다가 또 GameManager 스크립트를 첨부하고 기능을 동작시키려 해서 생긴 문제.
기본적으로 싱글톤은 하나만 존재해야 하지만, 여러 곳에 쓰였을 때 Awake()에서 새로 생성된 GameManager를 제거하도록 처리해 줄 수도 있다.
private void Awake()
{
if (gameManager == null)
{
gameManager = this;
DontDestroyOnLoad(gameObject); // 씬 변경 시에도 유지
}
else if (gameManager != this) // 이미 존재하는 인스턴스가 자신이 아니라면
{
Destroy(gameObject); // 중복된 GameManager 삭제
return;
}
// UIManager가 싱글톤인지 여부에 따라 다르게 처리
if (UIManager.Instance != null)
{
uiManager = UIManager.Instance; // 싱글톤 사용
}
else
{
uiManager = FindObjectOfType<UIManager>(); // 싱글톤이 아니라면 씬에서 찾아서 사용
}
}
이렇게 해주면 GameManager가 중복으로 생성되지 않아 UI가 여러번 조작되는 문제를 방지할 수 있다.