[Unity][2D-Game] Suika-Game (8)

suhan0304·2023년 11월 21일
0

유니티 - Suika Game

목록 보기
8/8
post-thumbnail

Review

  • 동글을 오브젝트 풀링 기법으로 생성한다.
  • 오브젝트 풀링의 모든 오브젝트가 사용 중일 시 새로운 오브젝트를 추가하고 풀에 추가한다.
  • 반환된 오브젝트는 추후에 재사용할 수 있도록 속성을 초기화 시키는 재사용 로직을 구현한다.

강의영상 (8) - 게임 완성하기


개발

변수 정리

게임 매니저의 변수들이 인스펙터에서 정돈된 상태로 나오도록 스크립트를 수정한다.

GameManager.cs

[Header("--------------[ Core ]")]
public int score;
public int maxLevel;
public bool isOver;

[Header("--------------[ Object Pooling ]")]
public GameObject donglePrefab; //동글 프리팹
public Transform dongleGroup;   //동글이 생성될 위치
public List<Dongle> donglePool;
public GameObject effectPrefab; //이펙트 프리팹
public Transform effectGroup;   //이펙트가 생성될 위치
public List<ParticleSystem> effectPool;
[Range(1, 30)]
public int poolSize;
public int poolCursor;

public Dongle lastDongle;
    
[Header("--------------[ Audio ]")]
public AudioSource bgmPlayer;
public AudioSource[] sfxPlayer;
public AudioClip[] sfxClip; //여러 효과음들이 담길 변수
public enum Sfx { LevelUp, Next, Attach, Button, Over };
int sfxCursor; //다음에 재생할 AudioSource를 가리킬 변수

[Header] : 인스펙터에 말머리를 추가


점수 시스템 완성

이제 UI로 점수시스템을 구현한다. 이 때 캔버스 UI의 Scale Mode를 Scale with Screen Size로 변경한다. 해상도는 1920*1080을 사용한다.

UI > Legacy > Text를 생성해서 텍스트 앵커를 Shift + Alt 키를 활용하여 왼쪽 위로 설정한다.

  • 글꼴은 Jua-Regular, 사이즈는 50으로 설정한다.
  • PosX, PosY = 50, -50로 설정한다.
  • Horizontal, Vertical Overflow를 둘 다 Overflow로 설정한다.
    - 텍스트가 지정 영역 상관없이 보이게 할 수 있다. ( Width, height에 상관없이 보인다.

게임 매니저의 인스펙터에 미리 선언한 Text에 드래그드랍해 초기화 시킨다.
UI 업데이트는 LateUpdate 함수를 사용한다.

GameManager.cs

if (!PlayerPrefs.HasKey("MaxScore")) //저장된 최고 점수가 없다면
{
    PlayerPrefs.SetInt("MaxScore", 0); //MaxScore라는 이름으로 최고 점수 저장
}
maxScoreText.text = PlayerPrefs.GetInt("MaxScore").ToString();

LateUpdate : Update 종료 후 실행되는 생명주기 함수

최고 점수를 위해 점수 텍스트를 Ctrl+D로 복사 후 재조정해준다.

  • 이름을 Max Score로 설정한다.
  • 우측, 상단 정렬
  • PosX, PosY = -50, -50으로 설정한다.
  • 색만 적절하게 변경한다.

PlayerPrefs로 최고 점수를 게임 시작 시에 불러오고 게임 오버시 최고 점수를 갱신하도록 로직을 구현한다.

private void Awake()
{
	~~(생략)~~

    if (!PlayerPrefs.HasKey("MaxScore")) //저장된 최고 점수가 없다면
    {
        PlayerPrefs.SetInt("MaxScore", 0); //MaxScore라는 이름으로 최고 점수 저장
    }
    maxScoreText.text = PlayerPrefs.GetInt("MaxScore").ToString();
}

IEnumerator GameOverRoutine()
{
	int maxSocre = Mathf.Max(score, PlayerPrefs.GetInt("MaxScore"));
	PlayerPrefs.SetInt("MaxScore", maxSocre);
}

게임 종료 UI

이제 게임 오버 UI를 만들기 위해 이미지 오브젝트를 생성한다.

스크립트에서 UI를 사용하기 위해선 UnityEngine.UI 네임스페이스를 추가해야한다.

  • 이름을 EndGroup으로 설정한다.
  • 앵커를 전체화면이 꽉차도록 설정한다.
  • 검은색 + 알파값을 20으로 설정한다.

이제 이미지, 버튼을 자식 오브젝트로 생성한다.

이미지
  • Sprite의 End를 Source Image로 설정한다.
  • Set Native Size 설정한다.
  • PosY = 70으로 설정한다.
버튼
  • Width, Height = 180, 130으로 설정한다.
  • Pos Y = -60으로 설정한다.
  • Source Image를 Panel로 설정한다.
  • 폰트를 Jua-Regular, 글자 사이즈를 30으로 설정한다.
  • 텍스트의 Pos Y = -30으로 설정한다.
  • 재시작 버튼 안에 점수표기를 위한 텍스트 오브젝트를 한 개 더 추가한다.
    - 이름을 SubScore Text로 설정한다.
    - Pos Y = 30으로 설정한 후 글자 사이즈를 20, 색을 적절하게 설정한다.

이제 게임 매니저 스크립트에서 그룹 오브젝트와 결과 텍스트를 저장할 변수 2개를 선언하고 인스펙터에서 초기화해준후 게임 오버될 시 해당 UI 활성화 및 결과 점수 텍스트 업데이트 되도록 구현한다.

GameManager.cs

IEnumerator GameOverRoutine()
{
    ~~(생략) ~~

    //최고 점수 갱신
    int maxSocre = Mathf.Max(score, PlayerPrefs.GetInt("MaxScore"));
    PlayerPrefs.SetInt("MaxScore", maxSocre);

    //게임 오버 UI 표시
    endGroup.SetActive(true);
    subScoreText.text = "점수 : " + scoreText.text;

    SfxPlay(Sfx.Over);
}

이제 버튼을 누르면 게임이 리셋되도록 재시작 함수를 선언한 후 버튼의 OnClick 이벤트에 해당 재시작 함수를 불러오도록 한다.

public void Reset()
{
    SfxPlay(Sfx.Button); //버튼 선택음 
    StartCoroutine(ResetCoroutine()); //리셋 코루틴 실행
}

IEnumerator ResetCoroutine()
{
    yield return new WaitForSeconds(1f); //1초 대기후
    SceneManager.LoadScene(0);           //0번 장면(게임씬) 로드
}

스크립트에서 장면 관리 담당하기 위해선 UnityEngine.SceneManagement 네임스페이스를 추가해야한다.

  • SampleScene의 이름을 Main으로 수정한다.
    - 이름을 수정하기 전에 게임 장면을 저장해야한다.
  • File > Build Settings > Scene In Build에서 장면을 확인한다.
    - Build Settings에서 위 LoadScene에서 사용한 장면별 인덱스를 확인할 수 있다.

장면이 여러개라면 빌드 세팅에서 Add Open Scenes로 장면을 불러와야한다.

게임이 끝나면 bgm도 멈추도록 stop 함수를 호출한다.

IEnumerator GameOverRoutine()
{
	~~(생략)~~
    
	bgmPlayer.Stop();
	SfxPlay(Sfx.Over);
}

게임 시작

게임종료 그룹을 Ctrl+D로 복사해서 게임 시작으로 변경 후 수정한다.

  • 배경 이미지는 흰색에 투명도 20으로 설정한다.
  • 이미지의 Source Image를 Title로 설정한 후 Set Native Size를 선택한다.
  • 버튼의 Width, Height = 180, 90으로 설정한다.
  • subScore Text는 삭제한 후 남은 Text의 Bottom을 15으로 설정한다.

추가적으로, 게임 시작 전에 보여줄 필요가 없는 오브젝트들을 비활성화해준다.

게임 시작 함수를 선언해서 비활성화한 오브젝트를 활성화해주면서 게임이 시작되도록 구현한다. 비활성화한 오브젝트를 변수로 선언해준 후에 인스펙터로 초기화 시켜준다.

기존 start 함수를 GameStart로 이름을 바꾼후 아래 코드와 같이 수정한다.

GameManager.cs

public void GameStart()
{
    //오브젝트 활성화
    line.SetActive(true);
    bottom.SetActive(true);
    wall[0].SetActive(true);
    wall[1].SetActive(true);
    scoreText.gameObject.SetActive(true);
    maxScoreText.gameObject.SetActive(true);

    //게임 시작 UI 비활성화
    startGroup.SetActive(false);

    bgmPlayer.Play();
    SfxPlay(Sfx.Button);

    Invoke("NextDongle", 1.5f);
}

Invoke : 함수 호출에 딜레이를 주고 싶을 때 사용하는 함수

이제 게임 시작 버튼에 GameStart 함수가 실행되도록 OnClick 이벤트를 설정한다.


모바일 빌드

이제 File > Build Settings > Player Settings 에서 회사 이름, 게임 이름, 아이콘 설정 등을 마무리한다.

실제로 PC용 게임을 제작해서 모바일 빌드를 진행하지는 않았다. 만약 추가적으로 모바일 빌드를 하고 싶다면 강의 영상을 참고해서 모바일 빌드를 진행하자.

PC에서 esc키, 모바일에서는 뒤로가기 버튼(Cancel)을 누르면 꺼지도록 스크립트에 추가한다.

GameManager.cs

void Update()
{
    if(Input.GetButtonDown("Cancel")) //모바일용 게임종료함수
    {
        Application.Quit();
    }    
}

결과물

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글