- 작성 중 -

 

게임을 만들면서 고민을 많이 했던 부분을 여기에 남긴다.

 

이 프로젝트를 하면서 데이터를 저장하기 위해 데이터 설계를 했어야 했고 잊고 있었던 관계형 데이터베이스를 다시 공부하는데 많은 도움이 되었었다.

제작 기간이 한 달 정도밖에 없었지만 게임 제작 전 설계가 중요하다고 생각되어 팀원들을 설득해 설계와 문서작성으로 10일 정도 작성하다 보니 구현할 수 있는 기간이 얼마 남지 않았다는 걸 알게 되었고 문서는 제쳐두고 급하게 프로토 타입 제작을 들어갔다.

 

서버 결정.

집에 그래픽 카드가 망가져서 내장 그래픽카드밖에 사용이 불가능했던 구닥다리 PC 본체가 하나 있었다. 이 PC를 예전에 졸업작품에 사용하기 위해 LAMP서버로 만들어두어 유용하게 사용했었지만 쿨러가 제 역할을 하지 못하여 CPU 온도가 삼겹살을 구워 먹을 수 있을 정도로 올라갔었다. 화제가 날 것 같아 서버를 꺼놓은지 어엿 1년... 학부생 때 아마존 클라우드 수업을 듣다 나도 모르게 큰돈이 빠져나가서 어디서 또 빠져나갈지 몰라 결제 카드정보를 지워놨었다. 요번에 확인해보니 돈을 안내서 계정이 막혀있었다. 그렇다고 또 내고 싶지는 않고... 개인 노트북에 로컬로 웹서버를 만들어서 사용하자니 다른 팀원들에게 업데이트할 때의 번거로움이 싫어서 하지 않았다. 사용하지 않으면 주기적으로 아예 서버가 꺼져버려서 다시 켜야 되는 번거로움이 있지만 구름 IDE를 이용하기로 했다. 기존에 사용했던 PHP가 아닌 Javascript로 만들어보고자 하였다.  

 

------------------------

 

버튼을 눌렀을 때 GameObject를 켜거나 껐을 때 on/off 기능을 직접 이벤트 함수를 만들어서 사용했었다.

게임을 반절 넘게 만들던 도중 문득 GameObject를 열고 닫을 때 단순히 열고 닫기만 하며 이외의 기능은 하지 않는 부분은 유니티에서 제공해주는 GameObject.SetActive를 활용하여 만들었으면 좀 더 빠르게 만들었을 것 같다는 생각을 했다. 알고는 있었지만 왜 이걸 이용하려고 생각을 하지 않았을까... 후우...

다음부터 다른 프로젝트를 할 때는 계속해서 SetActive(true)를 하여 오브젝트를 켰을 때마다 어떤 기능을 해야 하는 함수를 실행시켜야 한다면 아래 사진과 같이 OnClick() 부분을 설정하고 OnEnable()을 이용하거나 이것도 쓰기 싫고 더욱 간편한 방법을 사용하겠다고 하면 SetActive(true)를 했을 때 실행해야 되는 함수를 싹 다 버튼 컴포넌트 OnClick() 부분에 붙여놓기로 하자.

Inspector창에 Button 컴포넌트

이러면 꽤나 구현 시간이 단축된다.

 

----------------

게임이 처음 시작되면 로딩 화면이 나온다. 여기서 NetworkManager라는 싱글톤 클래스를 통해 서버와 연결을 시도한다. 서버와 연결이 되어있는지 체크하기 위해 쿨타임을 만들어 일정 시간마다 서버와 연결을 시도하도록 하였다. 최대 연결 시도 횟수를 설정하여 연결 성공과 실패 부분을 나누었다.

실패할 때에는 팝업을 나타나게 하여 재 연결 시 다시 연결을 시도할 수 있도록 하였다.

 

 

-----------------

-----------------

캐릭터 선택 창에서 UI나 데이터 처리 부분에는 큰 어려움이 없었다.

오른쪽, 왼쪽 버튼을 누르면 캐릭터가 전환이 된다. 이 부분을 구현하기 위해 꽤 많은 고민을 했었다.

캐릭터가 늘어난다고 해도 최대 4개까지만 캐릭터를 추가되므로 캐릭터들을 동서남북으로 세워놨다.

카메라 로테이터 오브젝트를 원형 중앙에 위치시킨 후 메인 카메라를 카메라 로테이터 오브젝트의 자식으로 두었다.

캐릭터 선택 버튼을 누를 때 카메라 원판 중앙에 있는 카메라 로테이터 오브젝트의 각도만 바꾸면 원하던 캐릭터 쪽으로 카메라를 돌릴 수 있었다. 각도를 바꾸면 바로 카메라가 돌아가므로 레이븐처럼 부드럽게 카메라가 움직여야 했다.

부드럽게 구현하기 위해 Mathf.LerpAngle을 이용하였다.

CameraRotator 클래스 구현

 

----------

 

 

NetworkManager를 싱글톤으로 관리하여 캐릭터 장비, 스텟을 웹서버와 주고받게끔 해놨다.

상점에서 11개의 장비를 사는 버튼을 누르고 바로 뒤로 가기로 나가버리면  장비가 서버 DB로 제대로 저장이 되지 않는 문제가 발생했었다.

 

11개 아이템을 구매 후 상점 창을 나가게 되면 ShopPopupPanel이 setActive(false)가 되는데 이때 ShopPopupPanel의 컴포넌트로 붙여져 있는 ShopPopupManager.cs파일에 장비 아이템 팩을 구입하는 코루틴 함수가 실행 중에 setActive(false)가 되어 데이터를 다 주고받지 못하고 끝나버렸기 때문이다.

ShopPopupManager.cs에 PurchaseEquipmenetItemPack() 코드를 보면 NetworkManager에 ISaveEquipmentItemsToServer()의 코루틴 함수를 실행시키는 것을 11번 반복한다. 

ShopPopupManager.cs
NetworkManager.cs

위의 동작을 다 수행하다가 꺼져버리니 통신이 제대로 안되었다. 이를 해결하기 위해 장비 테이블 설계 자체를 변경해볼 생각도 하고 아예 ShopPopupManager를 따로 빼서 별도로 관리하게끔 할까 생각도 해보고 별 생각을 다 해봤는데 크게 고치지 않고도 해결할 수 있는 방법을 찾아냈다.

 

아무것도 터치가 안되게끔 StandByPopupPanel을 하나 만든다. 그 후 구매할 때 StandByPoupPanel을 켜놓고 모든 통신이 성공적으로 끝났을 때 종료되게끔 해놨다. 1개의 장비를 구매할 때는 티도 안 나지만 11개의 장비를 구매할 때 약 0.3초 정도 이 팝업이 뜨다가 꺼져서 살짝 답답한 감이 있을 수도 있지만 크게 코드를 바꾸지 않고 해결을 했다.

 

 

--------------------------

 

 

 

Plane을 하나 만들어서 Position과 Scale 사이즈를 바꿔 왼쪽 하단쪽에 0,0,0으로 좌표를 맞춘다. Transform 값은 아래 사진과 같이 변경하였다.

왼쪽 하단 모서리의 좌표는 (0,0,0)이며 오른쪽 상단 모서리의 좌표는 (400, 0, 400)이 된다.

 

(Plane에 네비게이션을 만들고 구워준다. 플레이어 이동, 네비게이션에 관한 설정은 생략하겠다.)

 

---

 

달빛조각사와 비슷하게 UI를 만들어보았다.

맵 이미지의 왼쪽 하단의 모서리 좌표를 어떻게하면 얻을 수 있을까 이것저것 알아보고 실험하던 차에 방법을 찾았다.
맵 이미지의 앵커를 왼쪽 하단에 맞춘다. 이렇게 해야 이미지의 왼쪽 하단의 모서리 좌표를 구할 수 있기 때문이다.

 

맵 이미지의 좌표값을 얻는 방법은 RectTransform에 offsetMin을 이용하였다. (피봇 위치에 따라 값이 변경됨 피봇을 왼쪽 바닥쪽에 두었기에 offsetMin은 왼쪽 하단 모서리 좌표, offsetMax는 오른쪽 상단 모서리 좌표를 구할 수 있음)

근데 이렇게 하면 화면은 1280 x 720 Landscape로 하고 있는데 스크린 사이즈를 바꾸면 스크린을 터치할 때 픽셀 좌표값과 이미지의 왼쪽 하단의 픽셀 좌표값이 다르게 나온다. (나중에 다른 방법을 찾던가 해야겠다. 아무튼)

 

---

 

버튼 컴포넌트에 OnClick()이벤트 함수를 이용하여 이미지 터치를 처리하였다.

 

 

 

1. 클릭할 때 클릭한 위치의 스크린 좌표를 구해야 한다.

 

UI에서 클릭한 마우스의 스크린 좌표를 구하는 방법은 

- Input.mousePosition으로 좌표값을 얻거나 

- 이벤트로부터 마우스의 좌표를 가져오는 방법이 있다. (이벤트에서 y의 위치는 반전되므로 아래와 같이 연산을 한번 해줘야 한다.)

 

이외에 더 방법들이 있겠지만 나는 Input.mousePosition을 이용하여 좌표값을 가져왔다. (모바일 환경에서 터치를하여 좌표를 구하려면 Input.mousePosition으로 스크린 좌표를 얻을 수 없다. pc에서 실험용으로 하는거라 나는 이걸로 한거다.)

 

 

rectTransform.rect.size를 이용하여 맵 이미지의 사이즈를 구했다.

 

 

 

클릭한 좌표에서 맵 이미지의 왼쪽 하단 모서리 좌표값을 빼면 이미지 사이즈에서 클릭한 좌표값을 구할 수 있다.

이 값을 이미지 크기로 나누면 클릭한 위치의 비율을 알 수 있다.  이 비율을 실제 Plane의 사이즈로 옮기기 위해 Plane의 사이즈를 곱해주면 월드상의 좌표값을 구할 수 있다.

 

구현된 소스코드.

---

 

지도상에서 클릭을 해보니 

빨간색으로 표시한 부분을 클릭해봄.

 

클릭한 위치로 움직인다.

클릭한 위치로 네비메쉬 경로에 따라 플레이어가 움직임

 

---

테스트 영상

https://youtu.be/E-Bnp2C7fEw

 

-진행중-

 

Game

 

 

 

 

 

Monster tool

몬스터 툴 메인화면
추가할 몬스터의 난이도 선택
추가된, 불러온 몬스터 데이터 출력

 

 

Item tool

아이템 툴 메인화면
추가 시 아이템 종류 선택
추가 할 상점의 아이템 난이도 선택
아이템을 추가하는 장면
파일에서 불러온 상점 아이템 정보 출력

 

추가한 아이템 저장

 

 

 

소스코드

https://github.com/gkagm2/cpppractise/tree/master/cpptraining/ch1/Game/TextRPG

'게임 개발 > C++ console' 카테고리의 다른 글

미디 키보드 건반 프로그램  (0) 2020.01.14
마리오게임  (0) 2019.12.03
미로찾기  (0) 2019.11.07
빙고 게임 (Player vs AI)  (0) 2019.10.30
숫자 퍼즐 게임  (0) 2019.10.30

크아와 짬뽕된 미로찾기

 

 

 

 

소스코드

https://github.com/gkagm2/cpppractise/blob/master/cpptraining/ch1/Game/MazeGame.cpp

 

'게임 개발 > C++ console' 카테고리의 다른 글

마리오게임  (0) 2019.12.03
TextRPG  (0) 2019.11.12
빙고 게임 (Player vs AI)  (0) 2019.10.30
숫자 퍼즐 게임  (0) 2019.10.30
베이스볼 게임  (0) 2019.10.30

 

 

 

hard모드로 실행중
AI 승리

소스코드

https://github.com/gkagm2/cpppractise/blob/master/cpptraining/ch1/Game/BingoGame.cpp

'게임 개발 > C++ console' 카테고리의 다른 글

마리오게임  (0) 2019.12.03
TextRPG  (0) 2019.11.12
미로찾기  (0) 2019.11.07
숫자 퍼즐 게임  (0) 2019.10.30
베이스볼 게임  (0) 2019.10.30

 

소스코드

https://github.com/gkagm2/cpppractise/blob/master/cpptraining/ch1/Game/NumberPuzzleGame.cpp

'게임 개발 > C++ console' 카테고리의 다른 글

마리오게임  (0) 2019.12.03
TextRPG  (0) 2019.11.12
미로찾기  (0) 2019.11.07
빙고 게임 (Player vs AI)  (0) 2019.10.30
베이스볼 게임  (0) 2019.10.30

Baseball game

 

sorce

https://github.com/gkagm2/cpppractise/blob/master/cpptraining/ch1/Game/BaseballGame.cpp

 

'게임 개발 > C++ console' 카테고리의 다른 글

마리오게임  (0) 2019.12.03
TextRPG  (0) 2019.11.12
미로찾기  (0) 2019.11.07
빙고 게임 (Player vs AI)  (0) 2019.10.30
숫자 퍼즐 게임  (0) 2019.10.30

+ Recent posts