복학을 했다. 전공에 집중하고자 게임 개발 동아리 활동을 좀 줄이려 했으나, 교양 과목에서 일이 터졌다.
세계지리와 관련된 수업인데, 교수님이 이런 과목을 들으면서 각 나라가 어디 있는지 모르는 것은 말도 안된다며 갑자기 지도를 주셨다.
다다음주에 이 지도에 빈 칸 25개를 뚫어오겠다며 쪽지시험을 예고하셨다.
하지만.. 세계지리는 커녕 한국 지리도 잘 모르는 본인. 연습할 플랫폼이 필요했다.
어플을 찾아보는데 국기 맞추기, 수도 맞추기가 대부분을 차지하고 있더라. 문득 드는 생각. 어? 이거 프로젝트 각인데?
목표를 우선 세워보았다.
이미 다 만든 시점에서 후기글을 적고 있기 때문에, 결과만 말하자면 배포 예정은 없다.
이 프로젝트는 편하고 빠르게 개발하자!를 지향점으로 삼고 있었다. 복학과 함께 학원 강사를 병행하느라 쏟을 시간이 많지도 않고, 2주 남짓한 시간에 개발을 완료하고 쪽지시험 대비도 해야했기 때문에 빠르게 개발에 착수했다. 또한 볼륨이 커지면 프로젝트가 질질 끌릴 것 같아 최대한 가벼운 기능 구현만을 목표로 하였다(그렇게 유기한 프로젝트가 한 둘이 아니라..).
유니티로 만들기로 했다. 남은 시간이 많지 않아 가장 익숙한 플랫폼으로 결정했다.
목표 중 하나로, 지도를 어디선가 받아와서 적용하는 것이 있었다. 물론 직접 적당하게 경계선을 만든다던가, 좋은 이미지를 들고와서 sprite editor를 통해 분할할 수도 있지만 기왕 손을 들인거 의미있는 경험을 하고 싶었다.
찾아보니 포켓몬 고를 만들 때도 썼다던 OSM이란게 있더라.
여기서 국가경계선에 대한 JSON 파일을 받아오면, 어떻게든 적용 가능하겠지라는 생각으로 채택했다.
OSM에서 JSON 파일을 쉽게 뽑아올 수 있는 사이트가 또 있더라. 거기서 Overpass QL로 뭔가 이리저리 굴려주면 다양한 형태의 데이터를 얻을 수 있다.
하지만 문제는.. 이거 전체 국가경계선을 뽑아오려니 300MB면서 웹사이트에서 직접 다운로드를 하면 사이트가 터진다. 그래서 API를 통해 코드로 각각 국가경계선을 받아오는 방식을 택했다. 직접 일일이 할 수는 없잖아.
어떻게든 유니티에서 다 해결하고 싶었다. 찾아보니 에디터 레벨에서 유니티 코드를 실행할 수 있는 EditorWindow 클래스라는게 있더라. 자세한 사용 방식을 이 글에서 다루진 않겠다. GPT가 다 잘 알려줌. 대략 메뉴에 새로운 커스텀 버튼을 만드는 형식으로 진행된다. 런타임 중에 생성한 오브젝트는 런타임이 끝나면 사라지기 때문에, 규칙성이 있는 오브젝트 여러 개를 생성하고자 할 때 특히 유용했다.
에디터 레벨에서 JSON 파일을 다운로드받고, 각 나라의 국가경계선 좌표를 PolygonCollider2D에 넣어주는 식으로 오브젝트를 생성하면 이렇게 나온다.
사진에 보이다시피, 각 나라의 경계선이 이리저리 깨져있는 모습을 볼 수 있다. 가장 크기가 작은 파일(안도라, 40KB)의 각 세그먼트의 좌표를 살펴보니 각 세그먼트의 시작점과 끝점의 순서가 엉망이더라. 과제가 더 생겼다.
유니티의 에디터 레벨에서 자꾸 파일을 저장하고 읽어오는 것은 비효율적이라고 판단. 눈물을 머금고 파이썬으로 복귀했다. 세그먼트를 정렬하는 문제는 정리하면 다음과 같다.
양 끝점을 공유하는 세그먼트 , , ..., 이 주어질 때, 각 번째 세그먼트의 끝점이 번째 세그먼트의 시작점이 되도록 세그먼트를 정렬하라. 단, 세그먼트는 무작위로 주어지며, 뒤집힌 경우(두 세그먼트가 끝점/끝점을 공유하는 경우)도 존재한다.
보자마자 그래프탐색을 이용하면 되겠거니 했다. 좌표의 개수가 많은 것이지 세그먼트의 개수가 많은 것은 아니기 때문에, 으로 각 세그먼트의 연결 여부를 탐색하고, 두 세그먼트가 시작점인지 끝점인지에 따라 그 유형을 저장한다.
그렇게 만든 그래프로 임의의 점부터 시작하여 그래프 탐색을 돌리면(역방향인 경우 그리디하게 뒤집어주었다.) 다음과 같이 멀쩡한 세그먼트를 얻게 된다. matplotlib을 이용하여 디버깅해주었다.
이렇게 얻은 국가경계선을 다시 JSON 파일로 저장해주었다. 참고로 유니티에서는 Json.NET 라이브러리를, 파이썬에서는 json 라이브러리를 이용하였다.
파이썬에서 만들어온 JSON 파일로 오브젝트를 다시 만들고, LineRenderer라는 걸 이용해서 콜라이더를 시각화했다. 국가를 가로지르는 선이 없는 걸로 보아 세그먼트 정렬이 올바르게 됐음을 알 수 있다.
대략 배경색도 바꾸고.. 선 색깔도 보기 편한 색으로 바꿔줬다. 그리고 대충 기능 구현을 진행했다.
근데 이걸 위해서 입력필드에 한국어를 입력해야하는데, TMPro는 기본적으로 한국어 지원이 안되더라. 무료 글씨체로 FontAsset을 새로 만들어 주었다. 그외에도 다양한 컴포넌트에서 TMPro가 붙은 새로운 이름의 컴포넌트를 써야해 불편했다. GPT가 많이 도와줬다. 이 부분도 자세히 다루진 않겠다.
끝났다!
3/14에 아이디어가 떠올라 3/24 새벽에 완료한, 학원 일로 바빴던 주말 기간을 포함해도 10일 만에 개발이 끝났다.
토이 프로젝트긴 하지만 이번 프로젝트로 얻은 것이 굉장히 많다. 개인적으로 기승전결이 깔끔한 프로젝트였다고 생각한다. 우선 가장 큰 경험이라 생각하는 것은, 새로운 지식을 받아들이는 속도가 굉장히 빨라진 것 같다. 이번에 처음 써보는 것들이 꽤 많았는데 정말로 막힘없이 진행했다.
이번에 새로 다뤄보는 것들을 나열하면 다음과 같다.
OSM(OpenStreetMap)
Overpass API. API를 처음 사용해봤다.
JSON / Json.NET, json 라이브러리. JSON도 처음 다뤄봤다.
InputField와 이벤트 리스너
...
개인적으로 믿고 있는 것은 결국 개발할 때 어떤 형태의 데이터가 어떻게 이동하는지를 파악하면 어려울 게 없다고 생각했는데, 이번에 그 생각에 대해 자신감을 좀 얻은 것 같다.
또 두번째로, 이번에 얻고자 한 것은 편하게 개발하는 경험이었다. 항상 정보를 찾는 것이 어렵다고 생각했는데, 이번엔 GPT를 적극적으로 활용했다. 물론 실제 알고리즘을 써야하는 세그먼트 정렬 문제가 나올 쯤엔 좀 아찔했다. 하지만 알고리즘을 정말로 개발에 쓰는 실제 예시가 된다는 생각에 즐겁게 임했다. 마냥 편했다기엔 위기가 있었지만 이정도면 나쁘지 않았다.
다음 프로젝트도 이렇게 짧게, 올해는 내 역량에서 진행할 수 있는 난이도로 빠르게 끝내는 것을 목표로 계속 단기적으로 진행하지 않을까 싶다.
마지막으로 쪽지시험 점수다. 무려 만점을 받으며 정말로 실속있는 프로젝트의 방점을 찍었다. 기분 좋은 엔딩이다. 끝