상세 컨텐츠

본문 제목

13장 유니런(게임매니저, 싱글톤 패턴)

유니티/게임만들기

by MJ_119 2024. 3. 22. 00:13

본문

 @ 게임 매니저 역할

 - 점수 저장

 - 게임오버 상태 표현

 - 플레이어의 사망을 감지해 게임 오버 처리 실행

 - 점수에 딸따라점수 UI 텍스트 갱신

 - 게임오버되었을 때 게임오버 UI 활성화

 

@ 싱글톤 패턴 

 - 게임 매니저 오브젝트는 단 하나만 존재 ( 단일 오브젝트 ) 

 - 어떤 곳에서도 손쉽게 게임 매니저 오브젝트에 접근 가능 ( 손쉬운 접근 ) 

위의 조건을 만족할 때 보통 싱글톤 패턴 사용.

 

 - 정적 변수의 특징을 활용 (static)

 - 어떤 변수를 static으로 선언하면 / 여러 오브젝트가 해당 변수 하나를 공유함

 - 정적 선언된 변수는 특정 오브젝트에 속하지 않고 같은 타입의 모든 오브젝트가 공유함.

 

public static GameManager instance; // 싱글톤을 할당할 전역 변수(=정적 변수)

    // 게임 시작과 동시에 싱글톤을 구성
    void Awake() {
        // 싱글톤 변수 instance가 비어있는가?
        if (instance == null)
        {
            // instance가 비어있다면(null) 그곳에 자기 자신을 할당, 스스로 싱글톤을 할당함으로써 유일한 GameManager 오브젝트를 선언.
            instance = this;
        }
        else
        {
            // instance에 이미 다른 GameManager 오브젝트가 할당되어 있는 경우

            // 씬에 두개 이상의 GameManager 오브젝트가 존재한다는 의미.
            // 싱글톤 오브젝트는 하나만 존재해야 하므로 자신의 게임 오브젝트를 파괴
            Debug.LogWarning("씬에 두개 이상의 게임 매니저가 존재합니다!");
            Destroy(gameObject);
        }
    }

 

 

@ 게임오버시 씬 재시작

    void Update() {
        // 게임 오버 상태에서 게임을 재시작할 수 있게 하는 처리

        // 현재 활성화된 씬을 다시 로드하는 방식으로 구현
        if( isGameover && Input.GetMouseButtonDown(0) ) // 게임오버상태가 True + 마우스 왼쪽버튼 클릭시 
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().name); // 씬 재시작
        }
    }

 

 - SceneManager.GetActiveScene()

 : 현재 활성화된 씬의 정보를 Scene 타입의 오브젝트로 가져오는 메서드

 - SceneManager.GetActiveScene().name 

 : 현재 씬의 이름을 가져오는것.

 

 

@ 점수 증가 , 플레이어 사망했을 때 실행할 처리

    // 점수를 증가시키는 메서드
    public void AddScore(int newScore) {
        // 게임오버가 아니라면
        if (!isGameover)
        {
            // 점수 증가
            score += newScore;
            scoreText.text = "Score : " + score;
        }
    }

    // 플레이어 캐릭터가 사망시 게임 오버를 실행하는 메서드
    public void OnPlayerDead() {
        isGameover = true;
        gameoverUI.SetActive(true);
    }

 

 

@ 전체 스크립트

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

// 게임 오버 상태를 표현하고, 게임 점수와 UI를 관리하는 게임 매니저
// 씬에는 단 하나의 게임 매니저만 존재할 수 있다.
public class GameManager : MonoBehaviour {
    public static GameManager instance; // 싱글톤을 할당할 전역 변수(=정적 변수)

    public bool isGameover = false; // 게임 오버 상태
    public Text scoreText; // 점수를 출력할 UI 텍스트
    public GameObject gameoverUI; // 게임 오버시 활성화 할 UI 게임 오브젝트

    private int score = 0; // 게임 점수

    // 게임 시작과 동시에 싱글톤을 구성
    void Awake() {
        // 싱글톤 변수 instance가 비어있는가?
        if (instance == null)
        {
            // instance가 비어있다면(null) 그곳에 자기 자신을 할당, 스스로 싱글톤을 할당함으로써 유일한 GameManager 오브젝트를 선언.
            instance = this;
        }
        else
        {
            // instance에 이미 다른 GameManager 오브젝트가 할당되어 있는 경우

            // 씬에 두개 이상의 GameManager 오브젝트가 존재한다는 의미.
            // 싱글톤 오브젝트는 하나만 존재해야 하므로 자신의 게임 오브젝트를 파괴
            Debug.LogWarning("씬에 두개 이상의 게임 매니저가 존재합니다!");
            Destroy(gameObject);
        }
    }

    void Update() {
        // 게임 오버 상태에서 게임을 재시작할 수 있게 하는 처리

        // 현재 활성화된 씬을 다시 로드하는 방식으로 구현
        if( isGameover && Input.GetMouseButtonDown(0) ) // 게임오버상태가 True + 마우스 왼쪽버튼 클릭시 
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().name); // 씬 재시작, SceneManager.GetActiveScene().name => 현재 씬의 이름을 가져옴
        }
    }

    // 점수를 증가시키는 메서드
    public void AddScore(int newScore) {
        // 게임오버가 아니라면
        if (!isGameover)
        {
            // 점수 증가
            score += newScore;
            scoreText.text = "Score : " + score;
        }
    }

    // 플레이어 캐릭터가 사망시 게임 오버를 실행하는 메서드
    public void OnPlayerDead() {
        // 현재 상태를 게임오버로 바꿈
        isGameover = true;
        // 게임오버 UI를 활성화
        gameoverUI.SetActive(true);
    }
}

 

 

 

 

@ PlayerController 스크립트 수정. < 플레이어 죽는 순간 게임오버 처리 >

   private void Die() {
        // 사망 처리

        // 애니메이터의 Die 트리거 파라미터를 셋
        animator.SetTrigger("Die");

        // 오디오 소스에 할당된 오디오 클립을 deathClip으로 변경
        playerAudio.clip = deathClip;

        // 사망 효과음 재생
        playerAudio.Play();

        // 속도를 0으로 변경
        playerRigidbody.velocity = Vector2.zero;

        // 사망 상태를 true로 변경
        isDead = true;

        // 게임 매니저의 게임오버 처리 실행
        GameManager.instance.OnPlayerDead();
   }

 

플레이어가 죽는순간 실행하기 위해 마지막줄에 OnPlayerDead() 추가.

 

@ 게임오버인 상태에서 발판과 배경이 멈춰야 하기 때문에 ScrollingObject 스크립트 수정

private void Update() {
        // 게임 오브젝트를 왼쪽으로 일정 속도로 평행 이동하는 처리
        
        // 게임오버가 아니라면 실행
        if (!GameManager.instance.isGameover)
        {
            // 초당 speed의 속도로 왼쪽으로 평행이동
            transform.Translate(Vector3.left * speed * Time.deltaTime);
        }
    }

 

if문 추가

 

 

@ 실행 후 결과 확인

 

 

- 게임오버가 안된다면 Deadzone의 태그가 잘 설정 되어있는지 확인해보자

 

 

 

관련글 더보기