Unity/Unity Study

[Unity] 두번째 게임, '풍선을 지켜라' 마무리

Jee-U 2025. 1. 6. 17:19

'풍선을 지켜라' 게임

게임을 시작하게 되면 민트색의 쉴드로 아래 풍선을 네모난 블럭으로부터 지키는 '풍선을 지켜라' 게임이다.

오랫동안 지키는게 목적인 게임이며 게임오버 시 풍선이 빨간색으로 변하며 커지고 게임오버 창이 뜨게된다.

게임오버 창에는 현재점수, 플레이 동안의 최고점수가 뜨며 다시하기 버튼을 통해 게임을 다시 진행할 수 있다.

 


 

 

이 게임을 진행하면서 생각보다 큰 난관은 없었으나 저번에 작성했던 글에 있었던 점과 사소한 실수로 인해 생긴 오류들이 있었다.

게임오버 후 다시하기 창이 이상하다?

분명 이번판의 점수와 최고점수가 있어야하는데, 이번판의 점수는 맞으나 최고점수라는 숫자가 있어야 할 곳엔 최고점수가 있고, 점수가 있어야 할 곳은 0.00으로 표시되어있는게 아닌가.

그래서 얜 내가 어디서 놓쳤고 뭐가 잘못되었지 라는 생각으로 GameManager 스크립트를 한참동안 쳐다보았는데 혹..시 하는 생각으로 인스펙터 창을 보았더니

Hierarchy의 GameManager - Inspector

그냥 내가 Best Score 넣어둘 곳에 Best Score Title을 넣었으니 당연하게 생기는 현상이었다^^...

(왜 매번 한글자의 오타와 한가지의 실수로 인해 땅을 파고있을까...)

 

 

 

public text bestScore;

public Animator anim;

저번에 이어 GameManager 스크립트에 새 변수(최고점수를 표시할 UI/BestScore와 애니메이터)를 추가했다.

 

public void GameOver()
    {
        isPlay = false;
        // 애니메이터 추가 코드
        anim.SetBool("isDie", true);
        // 기존 Time.timeScale = 0.0f의 경우 지연없이 바로 게임종료가 되어 애니메이터가 보이지 않게되어 TimeStop변수로 추가하였으며 0.5초의 딜레이를 시키게 됨
        Invoke("TimeStop", 0.5f);
        nowScore.text = time.ToString("N2");

        // 최고점수가 있다면
        if (PlayerPrefs.HasKey("key"))
        {
            float best = PlayerPrefs.GetFloat("key");
            // 최고점수 < 현재점수 
            if (best < time)
            {
                // 현재 점수를 최고점수에 저장한다
                PlayerPrefs.SetFloat("key", time);
                // bestScore 텍스트필드에 time을 나타내라 라는 코드
                bestScore.text = time.ToString("N2");
            }
            else
            {
                // 현재점수 < 최고점수 = 아무것도 하지 않게 time에서 best로 변경
                bestScore.text = best.ToString("N2");
            }
        }
        else
        {
            // 최소점수가 없다면
            PlayerPrefs.SetFloat("key", time);
            // 현재점수를 저장한다.
            bestScore.text = time.ToString("N2");
        }

        endPanel.SetActive(true);

    }

    void TimeStop()
    {
        Time.timeScale = 0.0f;
    }

 

  • Invoke("메서드 이름", 딜레이 할 시간); : 호출할 메서드를 딜레이할때 사용
    - 반복할때는 InvokeRepeating을 사용
  • "key"는 원래 "bestScore"이었으나 오타 혹은 대소문자 변경을 방지하기 위해 'string key = "bestScore"'로 하여 key라는 변수로 표시하게 되었음
  • PlayerPrefs : PlayerPrefabs의 약자로 간단한 수치, 데이터를 직접 클라이언트에 저장하고 관리하는 유니티에서 제공해주는 데이터 관리 클래스
    int, float, string, bool 타입의 데이터를 저장한다. (밑의 내용 외에 내용은 참고하기)
    • 데이터 저장하기
      • PlayerPrefs.SetFloat/SetString("변수명", 숫자값/문자열);
    • 데이터 불러오기
      • PlayerPrefs.GetFloat/GetString("변수명");
        - 저장하기와 마찬가지로 Float - 숫자값, String - 문자열 로 확인
    • 데이터 모두 지우기
      • PlayerPrefs.DeleteAll();

 

해당 게임의 숙제는 게임이 진행되는 동안 화면 밖으로 나간 Square를 계속 없애주는 코드를 넣는것이었는데

화면 밖으로 나가더라도 계속 쌓여가는 Square 오브젝트들

밖으로 나가 사라졌음에도 계속 쌓여가는 Square들을 밖으로 나갔을 때 없애줘야 한다.

 

전에 '빗물받는 르탄이'에서 Ground에 닿으면 파괴(Destroy)시키는 코드를 생각하며 입력해주었다.

    void Start()
    {
        float x = Random.Range(-3.0f, 3.0f);
        float y = Random.Range(3.0f, 5.0f);

        transform.position = new Vector2(x, y);

        float size = Random.Range(0.5f, 1.5f);
        transform.localScale = new Vector2(size, size);
    }

	void Update()
    {
        if (transform.position.y < -5f)
        {
            Destroy(gameObject);
        }
    }

 

(y -5는 가로 맨 밑의 좌표)

매 프레임마다 반복적으로 실행해줘야 하기 때문에 Update 메서드에 변수를 추가하였으며

해당 코드 입력 후 실행하였을땐 게임 밖으로 나간 Square 오브젝트들은 정상적으로 사라지는것을 볼수있었다.

 

 

 

2주차 내용을 3주차 월요일에 끝낸건 자랑스럽지 않지만 그래도 포기하지 않고 진행하고 있는 나 잘하고있다고 칭찬해주고 싶다.
다만 공부해야할 내용은 많으니까 모르는 부분은 정리해가면서 한번 더 복습 꼭 하기로..
기본적인 내용에 대해서도 지난 강의 복습해가면서 꼭 익히자, 파이팅