Prosto

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

Programing/Unity 3D

따라하는 유니티 2D 프로젝트ⓑ -8

Prosto 2016. 10. 28. 06:05


따라하는 유니티 2D 프로젝트ⓑ 강좌 여덟 번째 시간입니다.

 

 

이번에 함께 할 작업은 블록 위에선 볼이 생성되지 않도록 예외 처리 작업을 해주고,

게임 클리어 조건을 만들고 클리어 시 게임 클리어 화면으로 전환하는 작업을 하겠습니다.

추가로 시간을 측정하여 게임 클리어까지 걸리는 시간도 확인할 수 있도록 하겠습니다.



그럼 시작하겠습니다.


가장 먼저 저번에 작업했던 프로젝트를 실행합니다.

그리고 순서대로 직접 따라하시면 됩니다.



블록 위에서도 볼이 생성되는 모습입니다.


이렇게 블록 위에서 볼이 생성되고

블록 위에서 볼이 왔다갔다하면 안 되겠죠?


이 부분에 대한 예외 처리를 해보도록 하겠습니다.



볼 생성할 때와 관계가 있으니

Scripts - Ball - BallManager 순으로 선택하여

스크립트를 실행합니다.



새롭게 checkEmptyNormalBallCollider라는 bool 변수를 선언합니다.

(EmptyNormalBall이 생성되었을 때 해당 볼 위치에 블록이 있는지 확인할 것입니다.)



void Update()에서는

마우스 좌측 클릭이 일어났을 때

emptyNormalBall을 활성화 시키죠?

이때 checkEmptyNormalBallCollider를 false로 초기화해주도록 합니다.

(false가 블록과 충돌이 일어나기 전 값인 거죠.)



그리고 함수 ActiveBall()에서

새로운 볼을 생성(활성화)할 때

먼저 조건으로 이동 거리(클릭 시작점부터 끝점의 거리)가

1 이상인지 확인합니다.


그 다음으로 새롭게 조건을 추가해줍니다.

if(!checkEmptyNormalBallCollider)를 추가하여

checkEmptyNormalBallCollider가 false(다른 블록과 충돌 안 함)

상태일 때만 새로운 볼을 생성(활성화)하도록 합니다.



그렇다면 BallKeeper 스크립트에도 변화가 생겨야겠죠?

(BallKeeper가 EmptyNormalBall에 사용된 스크립트입니다.)


BallManager를 받아서

충돌 체크할 때 Tag가 Block인 대상과 충돌했는지도 확인하도록 합니다.


윗 부분에 void Awake() 부분이 짤렸네요.. (아래 소스입니다.)

    BallManager bm;

    void Awake()

    {

        bm = GameObject.Find("GameManager").GetComponent<BallManager>();

    }



그리고 Prefab에도 변화가 생겨야합니다.

기존에서 Rigidbody 2D가 필요 없었지만

(EmptyNormalBall이 충돌체크하는 대상이 오직 NormalBall 뿐이었으니..)

이제 Blcok(rigidbody없음)과 충돌 체크를 해야하니

새롭게 리지드바디를 추가해줍니다.

Add Component - rig(검색) - Rigidbody 2D 선택



저번과 마찬가지로 Is Kinematic에 체크를 해줍니다.


그리고 게임을 실행하여 확인해보면,

블록 위에서 클릭한 뒤,

슬래시(스와이프)하여 볼을 생성하려고 하면


이렇게 아무런 반응이 없는 것을 확인할 수 있습니다.

(이제 블록 위에서 볼을 생성할 수는 없겠죠?)



그럼 다음으로 게임 클리어 조건을 만들어보도록 합니다.

이번에는 모든 블록을 제거하는 경우 게임 클리어하도록 만들겠습니다.

블록을 모두 제거하는 거니

모든 블록들을 생성해주던

BlockManager에서 처리해줘야 마땅하겠죠?



새로운 변수

nowAliveBlockNum을 생성합니다.

이 변수로는 게임 시작 시 만들어진 블록의 수를 세고(더해주고),

블록이 없어지면 반대로 수를 줄일 것(빼줄 것)입니다.



이렇게 SetNormalBlock(Vector3 pos) 함수에서

노말블록을 생성(활성화)해줄 때

nowAliveBlockNum을 1 더해줍니다.


(만약 게임 시작할 때 SetNormalBlcok을 20번 불러 블록을 20개 셋팅했다면,

nowAliveBlockNum = 20이되겠죠?)



그리고 이렇게 새로운 함수를 만들어줍니다.

Block이 파괴(비활성화)되었을 때 호출해줄 함수입니다.

외부에서 접근하여 사용해야 하니 public 형태로 만들어줘야겠죠?


(지금은 조건 달성 시 "게임 클리어"라고 콘솔에 띄워주기만 합시다.)



BlockInfo 스크립트로 가서

블록이 제거되면 BlockManager의 BlockDestroy 함수를 호출하도록 할까요?


static BlockManager blockM;

으로 static 형태로 BlockManager를 만들어 줍니다.


그리고 Awake()에서

blockM(BlockManager)를 GetComponent하고있죠?

(저번에 static 변수는 일반 변수와 어떤 점이 다른지 설명했습니다.

혹 기억이 잘 안 나신다면 찾아보시면 좋겠네요.)



GetDamage() 함수 내에

체력이 1 미만(0이하)일 때 블록이 없어지는 효과를 만들어줬었죠?


이 부분에서 blockM.BlockDestroy(); 함수를 호출해줍니다.



자, 그리고 실행해보면

블록이 없어질 때 카운트가 줄어드는 것을 콘솔 탭에서

확인할 수 있을 겁니다.



이렇게 마지막 하나까지 모두 없어지면

"게임 클리어"라는 글자가 출력되고요.



이제 실제 그에 맞는 UI를 만들고

해당 화면을 띄워주도록 할까요?


Canvas에서 마우스 우측 클릭한 후

UI - Panel 순으로 선택합니다.



Panel 이름을 GameClearPanel으로 바꿔줬습니다.

(이름 변경 F2, 더블클릭 아시죠?)



이렇게 필요한 부분을 변경해주시고요.

(저번에 왜 1.01, 1.01로 바꾸는지도 설명했죠?)



이번에는

GameClearPanel 위에서 마우스 우측 클릭

UI - Text 순으로 선택하여

Text를 추가해줍니다.



이렇게 Rect Transform 부분이나 Text 부분 모두 설정해주시고요.

(이 부분은 저번에 GameOverUI 만들 때도 해봤죠?)



GameOverPanel의 Button(Retry)은 그대로 사용할 것이니

선택하여 복사(ctrl+C) 붙여넣기(ctrl+V)한 후

GameClearPanel로 드래그 앤 드랍하여 옮겨주도록 합니다.

(윈도우에서 파일 옮기는 방법이랑 같습니다.)

(복/붙하여 사용하면 버튼 클릭 시 처리되는 기능이나 설정도 그대로 유지됩니다.)


그리고 GameClearPanel의 Color도 적당한 색상으로 변경해줍니다.



그리고 Game 탭을 보면 이렇게 UI 구성이 되어있는 것을 알 수 있을 겁니다.


뒤에 흰-회 색 패널,

Game Clear!라는 텍스트,

Retry라는 버튼으로 구성되어있죠?



그럼 UI 구성은 끝났으니

이제 GameClearPanel을 비활성화 해주시고요.


스크립트에서 필요할 때 활성화시켜주도록 합시다.



BlockManager 스크립트로 들어가

"게임 클리어" 문구를 출력하던 부분

바로 밑에

GameObject.Find("Canvas").transform.FindChild("GameClearPanel").gameObject.SetActive(true);

을 추가합니다.

(게임오버 처리를 할 때와 동일하게 접근하여 활성화시켜줍니다.)



실제로 조건을 만족시키면

게임 클리어 패널이 활성화되는 것을 확인할 수 있습니다.


그리고 밑의 Retry 버튼을 누르는 경우

(게임 오버의 Retry 버튼과 동일)


아래처럼 새롭게 게임이 시작되는 것을 확인할 수 있습니다.



그럼 이제 마지막으로

카운트 스크립트를 만들어

게임 클리어까지 걸린 시간을 측정해보도록 하겠습니다.

(누가 더 빨리 클리어하는지를 보는거죠?)


Scripts - UI 폴더에서

마우스 우측 클릭 후 Crate - C# Script 순으로 선택합니다.



이름은 CountSys라고 지었습니다.



그리고 게임화면에서 보여줄 Text도 추가해줍니다.

방법은 역시 우측 클릭 - UI - Text 순이겠죠?

CountTx라고 이름을 설정했습니다.



RectTransform, Text 모두 알맞게 수정해주시고요.



그리고 CountSys 스크립트를 열어

위와 같이 작성해줍니다.


이 부분에서 궁금한 부분이 있나요?

int형으로 count를 0.1초마다 1씨 증가하였고,

시간을 표시할 때는 /10과 %10을 이요했습니다.

(float은 아주 약간의 오차가 있어 int형으로 받아서 처리하도록 만들었습니다.)



그리고 마지막으로 GameManager 게임오브젝트에

CountSys 스크립트를 추가해주세요.


지금까지 많이 해봤듯이

드래그 앤 드랍으로 추가하시면 됩니다.


마지막으로 게임 실행해보면

게임 진행 중 카운트가 0.1초 간격으로 진행되고,

클리어하면 상단에 시간(멈춤=timeScale이 0이기 때문에)이 표시되는 것을 확인할 수 있습니다.




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

이번 시간에는 게임 마무리 과정으로 필요한 예외 처리와

클리어 조건을 주고, 클리어 시 그게 맞는 화면으로 전환시켜주는 처리를 했습니다.

그리고 클리어에 따라 차이가 있을 수 있게 시간을 측정하도록 했습니다.


다음 시간에는 이번 프로젝트ⓑ를 진행하며 만들었던 게임을

간단하게 안드로이드 어플(App)으로 전환시키는 작업을 해보도록 하겠습니다.

게임을 안드로이드나 애플(iOS)로 전환하기 위해서는 몇 가지 기본적인 처리도 해줘야하고,

게임에 따라 추가로 필요한 작업도 해줘야합니다.

다음 시간에 그 과정을 살펴보도록 하겠습니다.


고생하셨습니다. 같이 따라하며 해봤습니다. 도움은 좀 됐나요?

그럼 다음 시간에 마지막 프로젝트ⓑ의 마지막 강좌로 찾아보겠습니다.

(요즘 정신이 없어서 글이 늦어지네요.. 프로젝트ⓑ 후 프로젝트ⓐ,ⓑ 모두 완성형을 만들고,

 다음 프로젝트ⓒ를 준비하여 진행할 수 있도록 하겠습니다... 여담은 다음 강좌에서 더 하도록 하죠..)

 

 

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


Comments