회사의 재정 악화로 급하게 회사를 그만두게 되었다. 조금 혼란스러웠지만, 이런 때야말로 혼자 개발하기 딱 좋은 때라는 생각이 들었다. 마침 이직용 포트폴리오에 회사 코드를 첨부하기도 애매했었고, 1인 개발은 더욱 필연 같았다.
회사에서 새로 개발할 게임에 대해 이야기를 할 때, 늘 나왔던 말은 "빠르게 작업해서 빠르게 출시하자"였다. 그런데 늘 그렇게 되지 않았고, 루즈해지는 기간도 꽤 길었었다.
그래서 1인 개발이지만 이번에야말로 진짜로 빠르게 작업해서 빠르게 출시해보자! 라는 마음가짐으로 기획을 시작했었다. 내가 처음 계획한 기간은 기획, R&D, 개발, 디자인 합해서 40일이었다.
회사에서 일감을 Notion이나 Trello로 나누는 것이 편했었는데, 노션을 무료로 사용할 때에 제한들이 좀 있기도 하고 어차피 혼자 사용할 거라서 Obsidian을 사용했다.
이때쯤엔 이것까지 하면 되겠다 싶을 정도로 계획을 잡았다. 그리고 필요하다고 생각되는 일들을 정리해서 시각화했다.
체계적으로 개발을 하고 싶었고 처음 3일 정도는 기획을 하면서 일종의 R&D를 병행했다. 이번 프로젝트에서 가장 욕심냈던 부분은 "객체지향적인 프로그래밍"이었다. 클래스 구조를 잘 짜보고 싶었고 그러려면 시작이 가장 중요할 것이라고 생각했다. 그래서 애초에 개발 전에 디자인 패턴이나 SOLID 원칙 등 가장 기본적인 부분부터 다시 복습도 하고 몰랐던 부분도 공부했다.
회사 일이 아니고, 혼자서만 일을 하려다 보니 게을러지는 것이 가장 큰 걸림돌일 것이라 생각했다. 그런데 일을 하나하나 해치워가면서 하니까 너무 재미있었고 그래서 더 열심히 했다. 위에 보면 포도알이 참 예쁘게 찍혔다.
게임 안의 코드들은 내가 회사에서 배운 것, 사용하던 것들을 거의 그대로 사용했다. 여긴 포트폴리오가 아니니까 모두 다 세세히 적기보다는 재밌었던 작업, 힘들었던 작업 몇 가지 적어보겠다.
회사에서도 어드레서블을 사용하기는 했었다. CTO님이 세팅을 하시고, 나는 빌드할 때 조심조심 업데이트만 하는 정도였다. 잘못 건드리면 큰일 난다! 느낌이 강해서 "제가 해봐도 될까요?"라고 섣불리 말씀을 못 드렸었다.
프로젝트의 에셋 다운로드를 local이 아닌 remote로 설정해서 인터넷에서 다운받도록 하는 기능이 있는데, 이 기능을 사용하면 스토어에 등록되는 앱의 용량도 줄일 수 있고, 에셋을 게임 내에서 추가로 받는다던가 스토어에서의 패치 없이 CDN 스토리지를 업데이트하는 것만으로도 게임의 에셋 일부를 업데이트할 수도 있다.
그리고 저번 프로젝트에서 이 기능을 쓰시려다 잘 안 돼서 결국 local로 돌리셨다는 사실을 나는 알고 있었다. 너무 remote가 쓰고 싶었고 열심히 조사했다.
CDN 서비스는 아마존이 아닌 Cloudflare에서 R2라는 이름으로 무료로 제공하고 있었다. 돈 아꼈다는 생각에 너무 신났었는데, 이걸 사용하려면 내 도메인이 필요했었다. 내 세상이 무너졌다.
그런데 카페24에서 도메인을 550원에 파는 이벤트를 하고 있었다. 비록 1년이라는 기간 제한이 있었지만 그때 돼서 연장하면 될 일이었다. 몹시 신났었다.
DNS, 네임서버 등 뭔가 낯선 단어들이 많았지만 하나하나 세팅하면서 개발을 같이 했고, 결국 성공했다!
별건 아니지만 인터페이스를 진짜 찐하게 써봤다. 회사 일할 때는 만들어져 있는 부모 클래스나 인터페이스를 분석해서 내가 쓰는 정도였는데, 시작부터 내가 하려니까 더 재미있었다.
지금까지는 객체끼리 충돌 처리를 할 때 CompareTag를 사용하고 각각 다른 getComponent를 쓰는 정도였다. 보통 다들 그렇게 하는 것 같다. 그런데 그러면 태그마다 다른 케이스로 코드를 작성해야 하니까 OnTrigger 함수 안의 코드가 굉장히 길어지고 지저분했었다.
그래서 이번에는 충돌하는 오브젝트들에게 IInteractable이라는 인터페이스를 붙여주었다. 그러면 플레이어의 OnTrigger 함수는
//예시 코드
private void OnTriggerEnter2D(Collider2D collision)
{
IInteractable interactableObject = collision.GetComponent<IInteractable>();
if (interactableObject != null)
{
interactableObject.EnterSingleInteraction();
}
}
이게 전부다. 우물 안 개구리로서 작성한 코드라서 이게 더 좋은 코드가 맞는지 확신은 없지만 어마어마한 깔끔함에 이미 자지진 상태였다.
그림은 생각보다 빠르게 나왔었다. 프로젝트 시작한 지 7일 차에 캐릭터, 배경들의 이미지는 나왔었다. 그런데 애니메이션이 문제였다.
내가 원했던 애니메이션 스타일은 쫙쫙 늘어나고 띠용띠용거리는 귀여운 애니메이션이었다. 최근에 오구와 비밀의 숲을 인상 깊게 보기도 했고, 원래 그런 걸 좋아한다. 이건 한 장 한 장 이미지를 그려서 빠르게 교체하는 고전적인 방식으로 만드는 거라고 알고 있다. (혹시 그게 아니라면 제발 알려주세요)
그래서 한 번 직접 그려보려던 중 감이 안 와서 일단 납작해졌다가 늘어나는 정도만 Idle 애니메이션 용으로 해봤는데
즉시 포기했다. 이건 내가 접근할 만한 영역은 아니라고 판단했고 애니메이터 포폴 만드는 거 아니잖냐고 스스로를 달래면서 Spine을 사용하는 것으로 선회했다. 뼈대 하나하나 만지면서 애니메이션을 만드는 건 나름 재미있었다.
오브젝트가 지정된 위치에서 스폰이 돼야 하는데, 로컬 기준 (0,0,0)에서 스폰된 채 뭔가 버벅거리는 일이 계속 생겼었다. 내가 개발할 때 가장 힘든 부분은 “간헐적으로 나타나는” 버그인 것 같다. 이 버그도 10번에 3번 정도만 발생해서 도대체 뭐가 원인인지 알 수가 없었다. 이것 때문에 이틀 정도를 통으로 사용한 것 같다.
유니티 Discussion에 직접 질문했고 찐하게 해결했다.
https://velog.io/@jajup/Transform%EA%B3%BC-Rigidbody%EC%97%90-%EB%8C%80%ED%95%B4
1인 개발이라는 건 귀찮은 일까지 모두 혼자서 해야 된다는 걸 알고는 있었지만 뒤늦게 체감했다. 이번에 깨달은 건데 회사에서 내가 계속 해오던 일은 "틀"을 만들어주는 것뿐이고 기획자분들이 항상 그 틀 안에 내용물을 채워줬었는데 이게 보통 힘든 일이 아니다.
퇴사 전: 대화 기능 만들어주기
1인 개발: 대화 기능 만들고, 대사 채우고, 연출 위치,타이밍 잡기
퇴사 전: 데이터를 가진 캐릭터를 만들어주기
1인 개발: 데이터를 가진 캐릭터를 만들고 수많은 캐릭터에 데이터 채워주고 밸런스 신경 쓰기
등등… 저 데이터 테이블 채우는 부분이 너무 끔찍해서 거기서 가장 하기 싫었다. 동료의 소중함을 한 번 더 깨달았다. 차라리 개발을 시켜달라.
40일이라는 기간을 잡았었고, 39일 차에 모든 게 끝났다.
라고 생각했었으나, 생각보다 구글의 검토는 까다로웠다.
메타데이터가 올바르지 않다, 광고가 올바르지 않은 연령대를 타겟팅하지 않는다 등등 메일도 꽤 주고받았다. 진상이었나 싶기도 했지만 재촉도 좀 했다. ㅠㅠ 그렇게 계획한 날짜에서 11일이 지난 후. 글 작성 날짜 기준 어제 프로덕션으로 게임이 잘 올라갔다.
너무 기간에 집중한 탓인지 만들어놓고 보니 게임의 스케일이나 기술이 "자 포트폴리오입니다!"라고 하기에는 너무 소박한 것 같다.
이제 친구한테 맥북 빌려서 애플에도 한 번 앱을 올려볼 계획이다. 회사에서 애플 빌드를 하시는 분이 계셔서 내가 만져볼 기회가 없었다. 애플도 검토 단계에서 리젝을 참 잘 준다고 들었던 것 같은데 미리 긴장해야겠다.
어차피 이거 조금 고쳐라 저거 조금 고쳐라 정도이지 않을까. 결과나 메일 기다리는 시간이 더 길게 뻔하다. 미뤄뒀던 여러 가지 공부도 병행해야겠다.