Prosto

따라하는 유니티 2D 프로젝트ⓐ -9 본문

Programing/Unity 3D

따라하는 유니티 2D 프로젝트ⓐ -9

Prosto 2016. 9. 22. 07:37

 

따라하는 유니티 2D 프로젝트ⓐ 강좌 아홉 번째 시간입니다.

 

이번에 다룰 내용은 게임오버 처리와 그에 따른 UI 처리를 해보겠습니다.

(Tag 순서와 충돌 시 TagCompare 부분도 있습니다.

이번 시간을 통해 게임의 시작부터 끝까지가 완성되었습니다.

(앞으로는 BestScore, 추가적인 게임성을 높이는 부분 등이 남았죠.)

 

 

 

그럼 시작하겠습니다.

 

 

가장 먼저 저번에 작업했던 프로젝트를 실행합니다. 그리고 순서대로 직접 해보며 따라오시면 됩니다.

 

우리가 지금부터 할 작업은 볼과 장애물의 충돌에 따라

점수를 표시해주고 게임 종료를 알려주는 작업입니다.

 

먼저 충돌 처리, 우리가 저번에 기본적인 부분에 대해 처리한 부분을 확인해볼까요?

Scripts - Obstacle - ObstacleInfo.cs를 열어보세요.

 

이쪽 체크된 부분이 충돌처리 부분이였죠?

(OnTriggerEnter2D(Collider2D col)부분)

 

지금 실행해보면 장애물과 볼이 충돌하면

충돌 : Ball이라고 알려주는 것을 확인할 수 있을 것입니다.

 

이번에는 그 충돌처리에 대한 부분을 중점으로 업그레이드해보죠.

 

 

[Tag 시작]

먼저 우리가 이번에는 Tag도 적용하여 충돌 대상이 적합한 대상인지에 대하여 판단해보겠습니다.

Tag를 선택하기 위하여 Untagged 부분을 눌러주세요.

 

이렇게 나오는 스크롤 항목들 중 Add Tag를 선택합니다.

(우리가 쓸 새로운 Tag를 만드는 거죠.)

 

누르면 Inspector창이 이렇게 바뀌었을 것입니다.

Tags & Layers를 확인하고

'+'버튼을 누르면

Tag 0  New Tag 항목이 추가될 것입니다.

 

두 개를 추가하여 각각 이름을

Player와 GameManager로 입력해주세요.

 

 

자 이제 만든 태그를 적용시켜 봅시다.

Hierarchy 패널에서 Ball을 선택한 후 Inspector의 이름 밑

Tag 옆 Untagged를 눌러 만든 Player를 눌러줍니다.

 

GameManager도 Untagged를 GameManager로 바꿔줍니다.

[Tag 끝]

 

 

자 이제 충돌 대상을 확인하고 옳바른 대상에게만

함수처리를 해볼까요?

 

if(col.CompareTag("Player"))를 통하여 충돌 대상 오브젝트의 태그를 비교합니다.

만약 태그가 Player면 Debug.Log로 콘솔에 "플레이어와 충돌!"이라고 표시해줍니다.

 

(이렇게 충돌하면 문구가 등장하는 것을 볼 수 있죠?)

하지만 지금은 Console창에 로그만 찍힐 뿐, 별다른 반응은 없습니다.

우리가 이제 해야할 작업들이죠.

 

여기서 저번 시간에 Pause를 만든 것처럼 간단하게 Time.TimeScale = 0으로 멈춰버려도 적용이 잘 되겠지만,

이번에는 다른 방법으로 해봅시다.

그리고 나중에 이 화면에서 다른 처리를 해주고 싶으니

일단은 귀찮겠지만 스크립트들에 처리를 해주도록 하죠.

 

먼저 PlayerAction.cs을 수정하겠습니다.

변수들이 있는 부분에

bool freezeState = false;를 선언해주세요.

 

(실수로 커서가 올라갔었네요..)

저 드래그된 부분이 이전에 작성된 부분입니다.

if(!jumpOn) 바로 밑에 조건을 추가하여

if(!freezeState){ 드래그 내용 }

으로 수정해줍시다.

 

(게임이 종료되어 볼이 멈춤 상태일 때는 클릭이 반응하지 않도록 처리하는 부분입니다.)

(점프 체크, 클릭된 시간 체크 모두 말이죠.)

 

 

그리고 가장 밑에

public void FreezeBall() 함수를 추가합니다.

점프를 진행하던 중이면-> JumpAction 코루틴을 중지하고 jumpOn을 false로 전환합니다.

점프 중이 아니면 -> 모든 코루틴을 중지합니다.(카운팅 중일 수도 있고, 예외처리죠.)

그리고 마지막에 freezeState를 true로 바꿔줍니다.

(이제 얼음입니다 Update에서 클릭에 반응하지 않겠죠?)

 

 

다음으로 ObstacleInfo.cs로 돌아옵니다. (충돌이 일어났을 때 처리를 추가해주도록 하죠.)

void OnTriggerEnter2D(collider2D col)함수에

새롭게

 GameObject.FindWithTag("Player").GetComponent<PlayerAction>().FreezeBall();를 추가합니다.

이번에 GameObject를 찾을 때 아까 적용시켰던 태그를 이용해 찾죠?

(태그를 이용하는 게 더 좋습니다.)

 

이제 충돌이 발생하고, 그 대상이 Player라면

Player의 PlayerAction을 얻어와 거기에 있는 함수인 FreezeBall()를 호출하겠죠?

실제로 게임을 실행해보면 장애물과 충돌 시,

그대로 볼이 멈춥니다. 하지만 맵은 그대로 움직이고 있고, 스코어도 그대로 상승하고 있네요.

 

앞으로 처리할 부분들이 어떤 것인지 감이 오시나요?

 

다음으로 MoveMap.cs를 켜줍니다.

가장 밑에 public void FreezeMap()함수를 추가해줍니다.

내용은 speed를 0으로 바꿔주는 것밖에 없네요.

 

여기서 speed는 우리가 배경,오브젝트 이동속도로 지정해둔 부분이었죠?

(이 부분 속도를 올리면 맵 이동속도가 올라가겠죠?)

 

실제로 FixedUpdate()에서 speed 처리를 하는 부분이 여깁니다.

tile들의 pos.x를 왼쪽으로 speed만큼 이동해주고 있었죠.

 

그럼 다시 ObstacleInfo.cs로 돌아와서 이번에는 MoveMap에 추가한 함수를 적용시킵시다.

이렇게 아까와 같은 사용방법으로

GameManager를 찾아 MoveMap의 FreezeMap()함수를 호출했죠?

 

이제 게임 실행을 해서 결과를 보면 달라진 모습을 볼 수 있을 것입니다.

자 먼저 볼과 장애물이 충돌하면 그대로 게임이 멈춘 듯이 보이게 됐죠?

하지만 아직 스코어는 1초마다 100점씩 올라가고 있네요.

 

이것도 처리해줍시다.

ScoreManager.cs를 켜주세요.

public void EndCountScore() 함수를 만들어줍니다.

카운트 상승 중이든, 아니든 (점수에 관련된)모든 코루틴을 중지시킵니다.

(StopAllCoroutines();는 현재 스크립트의 모든 코루틴 중지입니다.)

 

그리고 다시 한번 plusIng - 현재 점수가 추가 중이었는지 확인합니다.

만약 추가 중이었다면 해당 변수를 false로 전환해주고,

추가 중이던 점수를 마저 올라간 점수로 넣어줍니다.

 

(이때 적용시키고 싶지 않다면 scorePoint를 pastScorePoint로 바꿔주고 텍스트도 바꿔주면 되겠죠?)

 

다시 ObstacleInfo.cs로 돌아와서 해당 함수를 적용시켜줍시다.

이렇게 다시 같은 방법으로 함수를 호출했습니다.

 

그 후 게임을 실행해보면

실제로 충돌 시 게임이 멈추는 것을 볼 수 있습니다.

이렇게 TIme.timeScale에 손대지 않고 정지를 만들어봤네요.

 

 

이제 플레이어에게 결과를 보여줘야겠죠?

지금부터 게임 결과에 대한 처리를 해주도록 합시다.

(먼저 UI 구성을 대략적으로 해줍니다.)

Canvas 우측 클릭 - UI - Panel 순으로 선택하여 패널을 추가해주세요.

(NormalUI, PauseUI 만들 때 했던 작업입니다.)

 

 

이름을 바꿔주고, 이번에는 이미지를 사용하지 않을 거이니

비활성화(체크 해제)해주세요.

 

다음으로 결과에 크게 나올 SCORE를 만들어 봅시다.

(이런 크기로..)

 

생성 방법을 알고계시죠?

(OverUI 우클릭 - UI - Text입니다.)

생성 후 이름 변경과 각종 설정을 해주도록 합니다.

 

 

저번에 했던 것처럼 편하게 또 만들기 위하여

복사 / 붙여넣기를 이용하여 하나 더 만듭니다.

 

이름 변경, 각종 설정들을 해주세요!

 

 

또 다시 복사 붙여넣기를 해주세요.

그리고 이름, 각종 정보를 수정합니다.

(여기서 pos 부분에 -1.907349e는 0과 같은 것입니다. float형인 부동소수점 방식에서....)

 

 

다음으로 버튼 생성을 해주도록 하죠!

이제 UI는 많이 해보셨죠?

 

이렇게 각종 설정을 또 적용해줍니다.

(저와 같게 하지않고 원하는 크기와 위치, 색상으로 하셔도 상관 없습니다.)

 

 

일단 이런 결과 형태가 나오게 만들었습니다.

(지금은 NormalUI와 OverUI 패널 모두 나오고 있죠.)

 

 

자, 이제 UIevent를 수정해줄 차례입니다.

 

normalUI와 pauseUI처럼 UI 전환할 수 있도록 해줘야겠죠?

 

이렇게 추가해줍니다.

normalPanel, pausePanel 추가했던 것과 똑같죠?

 

가장 밑에 새로운 함수로 public void SetGameOverUI()를 만들어줍니다.

함수가 불리게 되면 normalPanel은 비활성화,

overPanel은 활성화되겠네요.

 

 

그렇다면 또 다시 ObstacleInfo.cs로 돌아와서 추가해줄까요?

이렇게 UIevent의 SetGameOverUI까지 등록해주면

이제 게임오버 시 UI 전환까지 되게네요!

 

그럼 실행하기 전에

OverUI를 비활성화 해두도록 하죠.

이렇게 선택하고

Inspector창의 체크를 눌러 해제해줍니다.

이렇게 해제하면 Hierarchy 패널에서도 옅은 색으로 변하죠.

 

실제 게임 화면에서도 이제 OverUI는 가려졌네요.

진행 중 필요할 때 활성화시켜주니 평상 시에는 꺼줘야겠죠.

 

이제 게임 실행을 하고 장애물과 충돌해봅시다.

이렇게 충돌 시 패널 전환(normal -> over)과

우리가 설정해둔 UI까지 제대로 나오는 것을 확인할 수 있습니다.

 

그럼 이제 출력되는 수치를 조정해볼까요?

UIevent.cs를 실행시켜

using UnityEngine.UI;를 입력해줍니다.

(UI 관련 기능을 해당 스크립트에서 사용하기 위해서죠?)

 

먼저 IEnumerator GameOverScoreCount() 코루틴 함수를 만들어줍니다.

그리고 SetGameOverUI() 함수에서 StartCoroutine으로 실행시켜주는 거죠.

 

자, GameOverScoreCount 코루틴 함수를 좀 볼까요?

(일단 저는 이 함수에서 카운트 방식을 점점 빠르게 수치가 상승할 수 있도록 만들었습니다. 가속도 느낌으로요.)

 

여기서 주황색 점은 Text 사용을 위한 부분입니다. 선언하고 바꿔주고있죠.

 

다음으로 하늘색 부분은 실제 점수 관련 부분입니다.

tempScore를 이용하여 중간 점수를 표시하고 있죠?

 

마지막으로 노란 점은 가속도 표현을 위한 부분입니다.

처음에는 0.15초 간격으로 100씩 증가하다가 한 번 증가할 때마다 0.005초씩 감소하여

마지막에는 0.02초마다 100씩 증가하여 보여주고 있죠.

 

 

이제 OverUI의 Retry 버튼에도 다시시작 기능을 적용시켜줍시다.

우리가 저번에 만들어뒀던 PauseUI에서의 Retry와 똑같이 적용합니다.

1. RetryBt 선택

2. '+'눌러 이벤트 추가

3. 오브젝트에 GameManager를 드래그 앤 드랍

4. 함수 적용.

 

자 실행해서 실제로 카운트가 되는 것을 확인하고,

Retry 버튼도 눌러봅시다.

 

정상적으로 다시 시작되고 있죠?

볼의 위치나 스코어, 일시정지 버튼 모두 처음 시작화면과 같습니다.

 

 

(이번 시간의 결과물)

 

 

지금까지 따라하는 유니티 2D 프로젝트ⓐ -9번 강좌를 보셨습니다.

이번 시간에는 이런 아케이드 게임의 끝을 나타낼 수 있는

게임 결과 화면을 구성하고, 실제로 끝을 만들어봤습니다.

(마지막에 점수를 카운트해주기도 하고요.)

아직 게임 종료에 들어갈 요소들을 다 넣지는 않았지만,

게임의 시작부터 끝이 완성되었네요. 완성입니다!

(하지만 아직 BestScore 처리도 안 됐고...

  게임성도 부족하고, 뭔가 부족하죠? 이제 진행하며 부가적인 부분들을 처리해갈 겁니다.)

 

 

 

다음 유니티 2D 프로젝트ⓐ의 열 번째 강의에서는..

Best Score를 PlayerPref을 이용하여 실제로 데이터를 저장해보고 신기록에 대한 부분도 처리해보겠습니다.

또, 게임의 추가적인 요소에 대한 부분도 드디어 들어갈 수 있겠네요.

(음.. 마지막 장면 애니메이션을 넣고 싶지만...)

 

 

고생하셨습니다. 따라오며 하니 어떤가요? 도움은 좀 됐나요?

그럼 프로젝트의 다음 단계를 진행하며 나오는 새로운 것들에 대해서는

지금과 같이 설명하며 진행하도록 하겠습니다.

 

궁금한 점 있으시면 댓글이나 따로 메일로 질문하시면 시간되는 대로 답변드리겠습니다. ( 연락 )

Comments