이번엔 떨어지는 네모로부터 동그라미(풍선)을 지켜 오래 살아남는 게임을 만들어 봤다. 만드는 과정에서 전날에 배웠던 것들을 복습하는 동시에 새로운 개념들까지 배울수 있었다!
이 풍선 지키는 게임은 지금 모바일 게임 시장에 이미 잘 팔린 전례가 있다. 이걸 토대로 잘 발전시켜 나가면 비슷한 아류작으로라도 출시할수 있을것같다.
1. 기본 씬 구성
전날에 했던것처럼 레이아웃을 편하게 바꿔준후 간단히 2d 스프라이트들로 씬을 구성했다.
이번 시간에는 UI까지 한번에 미리 만들어줬다.
2. 풍선/마우스 : 풍선 애니메이션
역시 이전에 했던것처럼 애니메이션을 만들어 주는데, 이번엔 두가지 스프라이트를 가져온게 아니라 단순히 색깔이 변하는 정도로 했다. 스프라이트의 색과 사이즈 등의 수치도 애니메이션으로 활용할수 있다는걸 배웠다.
3. 풍선/마우스 : 마우스 움직임 구현
여기서부터 스크립트가 다시 돌아왔다.
마우스로 움직일 오브젝트안에 이렇게 스크립트를 넣어주면 마우스를 잘 딸아다닌다.
4. 장애물 : 중력과 위치
역시 이전에 했던 부분을 되짚어보듯이 했다. 이전 게임에선 물방울이 떨어졌는데, 그때처럼 RigidBody2D 컴포넌트를 적용해주고 무작위 위치값을 정해줬다.
사이즈의 경우 강의에선 하나의 랜덤값으로 사이즈를 정해서 전부 정사각형이 나왔는데, 나는 이점이 지루하다고 생각해 가로세로 사이즈가 전부 랜덤으로 들어가게 조정했다. 이 값을 더 극단적으로 만들어주면 더 웃길것같다.
5. 장애물 : 랜덤 생성
여기서부터 다시 GameManager가 등장한다. 그전에 이 게임메니저가 씬에서 오브젝트를 가져올수 있도록 장애물을 프리팹화 해줘야 한다.
프리팹화를 하면 GameManager의 스크립트로 불러올수 있도록 적어줄수 있다.
먼저 반복실행할 기능을 코드 아래쪽에 미리 만들어준 뒤,
이렇게 실행할때 반복해주는 함수를 만들어주면 장애물이 반복 생성되고, 반복 생성될때 장애물(Square)에 넣어준 함수대로 랜덤한 값으로 등장하게 되는것이다.
6. 시간 구현
게임의 시간 또한 GameManager 안에서 구현해주게 된다.
시간을 구현하기 위해 우선 시간을 담아줄수 있는 함수가 필요하다.
그리고 프레임당 업데이트 해주는 기능인 Void update에서 시간을 하나씩 추가해주는 기능을 넣으면 된다.
이렇게 되면 시간이 0에서 1씩 더해지게된다. 하지만 만들어둔 UI 텍스트에 이 시간을 반영시켜야한다.
이렇게 time값을 텍스트에 문자열로 반영시켜줬다.
7. 게임 끝내기 : 게임종료 판넬
이제 풍선을 지키는대 실패했을때 게임을 끝내는 효과를 주기로 했다. 일단은 게임 종료 ui부터.
이렇게 강의를 따라서 만들어봤다.
하지만 이건 게임이 끝났을때만 보여야 하므로 이렇게 꺼놨다. 이제 게임이 끝났을때 이 ui가 켜지도록 코딩을 해주면 된다.
8. 게임 끝내기 : 게임 종료 로직 -> 최고 점수 구현하기 -> 풍선 애니메이션
게임 종료 로직 또한 GameManager에서 구현해주게 된다.
게임메니저를 싱글톤 처리해야한다고 하는데, 이렇게 해야 불러올수 있다고 한다, 아직 제대로 이해한것이 맞는지는 확실치 않지만, 어떻게 작동해서 어떤 결과가 나오는지는 이제 알기 때문에 일단은 넘어가기로 했다.
이제 게임이 끝나는 효과를 구현할 시간. 게임이 끝나서 발생해야 할것은
1. 게임 종료 판넬이 켜진다.(리트라이 버튼과 함께)
2. 풍선의 사망 에니메이션이출력된다.
3. 시간이 멈춘다.
이다. 완성된 GameManager 코드는 다음과 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public GameObject square;
public GameObject endPanel;
public Text timeTxt;
public Text nowScore;
public Text bestScore;
public Animator anim;
bool isPlay = true;
float time = 0f;
string key = "bestScore";
private void Awake()
{
if(instance == null)
{
instance = this;
}
}
// Start is called before the first frame update
void Start()
{
Time.timeScale = 1f;
InvokeRepeating("MakeSquare", 0f, 1f);
}
// Update is called once per frame
void Update()
{
if (isPlay)
{
time += Time.deltaTime;
timeTxt.text = time.ToString("N2");
}
}
void MakeSquare()
{
Instantiate(square);
}
public void GameOver()
{
isPlay = false;
anim.SetBool("isDie", true);
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.text = time.ToString("N2");
}
else
{
bestScore.text = best.ToString("N2");
}
}
//최고점수가 없다면
else
{
PlayerPrefs.SetFloat(key, time);
bestScore.text = time.ToString("N2");
}
// 현재 점수 저장
endPanel.SetActive(true);
}
void TimeStop()
{
Time.timeScale = 0f;
}
}
숙제 : 떨어지는 장애물 없애기
마지막으로 해결할 문제가 하나 남았는데, 바로 장애물이 생성되어 떨어질때마다 떨어진 장애물은 씬에 계속 남는다는 것이였다.
이렇게 되면 시간이 오래 지날때마다 데이터가 계속 쌓여 게임이 느려지는 문제가 발생할수도 있다.
나는 이 문제를 장애물이 특정 Y값을 넘어갈때 스스로 파괴되는 기능을 넣어서 해결했다.
'게임개발 > Unity' 카테고리의 다른 글
24-08-22 [고양이 밥주기 게임 下 ] (0) | 2024.08.22 |
---|---|
24-08-21 [고양이 밥주기 게임 上] (1) | 2024.08.21 |
24-08-19 [빗물받는 르탄이] (0) | 2024.08.19 |
티라노는 못참아 (0) | 2024.08.12 |
Unity 알아보기 (0) | 2024.08.12 |