Share
Sign In

Concode

데브 로그
그레이테일 2번째 공식 개발기 입니다.
안녕하세요! 개발자 MJ와 SH입니다! 지난 개발기 이후로 3개월이 훌쩍 지났네요. 그동안 정말 가열차게 게임을 만들었습니다. 그동안 작업된 내용을 알려드리고, 글의 마지막에서 저희 일정까지 공유드립니다. 2챕터 미니보스 - 데쓰 웜 2챕터에서 등장하는 미니보스인 데쓰 웜은 길고 거대한 몸통을 가진 벌레로, 빠른 돌진 공격을 합니다. 이 괴물은 땅속으로 파고들 수 있어, 주인공이 공격을 피하는 데 어려움을 겪게 만듭니다. 몸통이 끊어지면 2개의 작은 벌레로 분리되어 계속해서 공격을 이어가며, 전투가 점점 더 복잡해집니다. 2챕터 메인 보스 - 굴착기 2챕터 보스 Excavator는 거대한 두 개의 톱날을 장착한 기계로, 매우 강력하고 견고하여 외부에서의 공격만으로는 무너뜨릴 수 없습니다. 플레이어는 이 기계의 내부로 침투하여 파괴해야 하며, 내부에서는 예상치 못한 특별한 인물과의 만남이 기다리고 있습니다. 열기구 신호탄을 쏘면 마을의 안전요원 NPC가 열기구를 타고 주인공에게 다가와 마을로 데려다 줍니다. 열기구를 이용하면 빠르게 마을로 돌아갈 수 있습니다. 열기구는 또 마을을 둘러보는 투어용으로도 이용될 수도 있습니다. 전선 시스템 새로운 퍼즐 요소로 전기 플러그를 활용한 전선 시스템이 추가되었습니다. 플레이어는 플러그를 콘센트에 꼽고 빼가며 퍼즐을 풀어나갑니다. 예를 들어, 플러그를 이용해 팬을 돌리거나 특정 기계 장치를 작동시킬 수 있습니다. 레일 시스템 광산차를 타고 레일을 따라 빠르게 이동할 수 있는 시스템이 추가되었습니다. 이 시스템을 통해 이글거리는 용암지대와 같은 위험한 지역도 무사히 통과할 수 있습니다. 스위치를 사용해 레일의 방향을 바꿀 수 있어 퍼즐을 풀며 탐험을 이어가야 합니다. 플랫폼 및 톱날 함정 레일을 따라 이동하는 플랫폼과 위험한 톱날 함정도 추가되었습니다. 플랫폼을 이용해서 던전의 깊숙한 곳으로 탐험이 가능합니다. 톱날 함정은 빠르고 강력하기 때문에 조심해야 합니다. 바이크 개선 야간 라이딩을 지원하는 조명이 추가되었습니다. 다양한 야간 컨텐츠도 준비 하고 있습니다. 추가 몬스터 톱날 기계와 챕터 1의 추가 지역에 등장하는 개구리등 여러 몬스터가 추가 되었습니다. 각 몬스터마다 고유한 특성이 있어 플레이어는 그에 맞는 전략을 구사해야 합니다. 반응형 워터 시스템 물에 무언가 빠지거나, 배가 지나가거나, 헤엄치거나 할때 사실적인 물결 표현이 추가되었습니다. 마을 마을에는 식재료를 파는 상점과 점성술사의 집등 몇개의 추가 건물이 생겼습니다. 상점 주인, 낚시꾼, 점성술사, 안전요원 등 여러 NPC도 추가로 생겨 마을이 좀더 풍성해졌습니다.
  • Concode
3
👍
6
스팀 공식 페이지에 첫 개발기를 올렸습니다.
스팀 페이지에서 공식 개발기를 볼 수 있습니다! 페이지의 내용은 영상으로도 확인 가능합니다 :) https://www.youtube.com/watch?v=M_WKzILIdSg
  • Concode
👍
4
종이 접기의 마스터 - 2.5d 생존기
신작게임 그레이 테일은 3D 지형의 배경에 2D 픽셀로 된 캐릭터와 오브젝트가 배치되는 2.5D의 게임입니다. 하지만 직교 좌표계 카메라를 사용해서, 언뜻 보기엔 그냥 픽셀 2D 게임인 것처럼 보이게 만들고 있습니다. 2.5D의 장점 이런 방식을 사용하면, 높이 축을 사용할 수 있기 때문에 좀 높낮이가 적극적으로 들어간 맵을 디자인 할 수 있고, 자연스러운 그림자와 같이 3D에서만 가능한 여러가지 시각 효과들을 사용 할 수 있다는 장점이 있습니다. 캐릭터와 오브젝트는 여전히 2D 방식을 사용하고 있기 때문에, 2D 게임을 만들 때와 동일하게 Aseprite만으로 작업 하고 있습니다. 저희 같은 2인의 작은 스튜디오에서 따로 모델링, 리깅, 애니메이션 작업이 필요 없이 일을 쳐낼 수 있다는 것이 장점입니다. 2.5D의 문제 하지만 이런 방식도 몇가지 치명적인 문제들이 있습니다. 겪었던 문제를 나열해 보자면.. 너무 높이 판단에 정직합니다. 이펙트가 땅속을 파고 듭니다. 이런 문제는 이펙트를 캐릭터 스프라이트에서 분리시키고, 바닥을 향하는 Quad를 만들어 해결할 수 있습니다. 하지만 분리하기 애매하거나 작업이 몹시 번거로은 오브젝트들도 있습니다. 그래서 이번엔 스프라이트를 접어보기로 했습니다. Aseprite 에서는 그냥 전개도만을 그려주면 되고, 코드로 메시를 동적으로 생성해서 큐브를 생성합니다. 이런 식으로 제작하면 높이가 있는 오브젝트 위로 올라가거나 할때 오더링 문제로 부터 자유로워 집니다. 박스 Sprite 스크립트는 다음과 같은 인자를 통해 이미지만 넣으면 알아서 메시와 텍스쳐의 uv를 구성해주게 했습니다. 디자이너가 따로 모델링과 텍스쳐 매핑 작업을 할 필요가 없으니 작업이 훨씬 쉬워집니다. 하지만 모든 오브젝트가 Box 형태일 수는 없는 법.. 그렇게 스프라이트 종이접기가 하나씩 늘어나게 되고.. 지금 까지 대부분의 물체들은 종이접기로 대충 해결해오고 있었습니다. 하지만 종이접기로는 도저히 불가능해 보이는 것들이 생기기 시작하는데.. 점프대 게임의 던전이 아닌 넓은 필드 지대에서 "바이크"를 탈 수 있게 하면서, 바이크를 위한 점프대를 넣기로 했습니다. 그래서 만든 점프대의 스트럭쳐가 왼쪽인데.. 이건 도저히 접어서 어떻게 해결이..
  • Concode
6
❤️
10
RLE를 UTF8 이용 Fog of War 시리얼 라이즈
신작 게임에서는 앞선 글에서 이야기한 Fog of War 가 구현되어 있습니다. 맵 상에서 내가 방문한 곳과 하지 않은 곳이 저장된 2차원 형태의 텍스쳐와 비슷합니다. 대략 아래 처럼요. 게임을 껐다가 이어서 할 때, 내가 방문한 지역의 기록이 없어져 버린다면 다시 장님이 된 느낌일 것입니다. 그래서 이 2차원 텍스쳐를 저장해 줘야 합니다. 최대 맵의 크기가 128 x 128일때 방문/비 방문의 정보를 저장한다고 하면, 128x128 bytes (대략 16kb) 가 됩니다. 16kb면 큰 용량은 아니지만, 방문하는 지역이 여러곳이 되면 용량이 꽤나 커질 수 있는데다가, 데이터를 저장하고 로드할때 속도가 느려지기 때문에 이를 줄여주는 것이 좋습니다. 다음과 같은 여러가지 방법을 사용해 볼 수 있습니다. 1 byte에 8칸의 정보를 저장한다. (1/8 사이즈 압축) 범용 압축 알고리즘 이용 (lz4, Brotli 같은) Run Length Encoding 이용 몇가지 방법을 고려해봤지만, RLE를 이용하는 것이 데이터의 형태상 가장 쉽고 압축율도 좋을 것 같습니다. 구현도 매우 편하구요. Run Length Encoding Run-length encoding(RLE)는 매우 간단한 비손실 압축 방법으로, 데이터에서 같은 값이 연속해서 나타나는 것을 그 개수와 반복되는 값만으로 표현하는 방법입니다. 일반적으로는 다음과 같이 인코딩 합니다. 하지만 저희는 0과 1이 반복이기 때문에 굳이 키를 적어줄 필요가 없습니다. 따라서 다음과 같이 표현해줄 수 있습니다. 이때 count가 가질수 있는 최대값은 맵의 전체 크기인 128x128(16384) 입니다. 따라서 count를 표시하는데는 2byte short 이면 충분합니다. 하지만 맵에서 방문한 곳이 늘어나게 되면 128이하의 길이를 갖는 부분이 늘어날 수 밖에 없고 이 때 count를 저장하기 위해 2byte를 사용하는 것은 조금 아깝게 됩니다. 가변 너비 인코딩
  • Concode
👍🎮
8
Reflection
물이나 지면의 반사는 게임을 좀 더 사실적으로 만듭니다. 픽셀 그래픽에 붙어있는 Reflection은, 3D의 Reflection과는 다른 맛이 있는 것 같습니다. Reflection 구현 방법 게임에서 반사를 구현하기 위해 주로 다음 방법이 사용됩니다. Screen Space Reflection Planar Reflection Ray Tracing (이건 PC에서, RTX only로 사용됨)​ 저는 Unity를 사용하지만, 반사에 대한 내용은 언리얼 도큐먼트에 잘 정리되어 있습니다. https://docs.unrealengine.com/5.2/ko/reflections-environment-in-unreal-engine/ Screen Space Reflection 이 방법의 장점은, 스크린 스페이스에 반사가 일어나기 때문에, 성능면에서 비교적 빠르다는 점입니다. (그렇다고 막 써도 될정도는 아닙니다.)​ 단점은, 스크린 스페이스라, 화면에 그려지지 않는 오브젝트는 반사가 일어나지 않습니다. 또한 반사를 계산하기 위에 노말 벡터를 읽어야 하는데, 스크린 스페이스의 노말벡터는 포워드 렌더러에서는 가져올수 없습니다. 디퍼드 렌더러로 변경 후 G 버퍼에서 노말벡터를 가져올 수 있는데, 디퍼드 렌더러를 쓰면 반사가 있는 투명한 물을 만들 수 없습니다. (평면 반사로 한정하면 가능할 것 같기도 합니다.) 그리고 오브젝트에 가려진 뒷 배경은 스크린에 정보가 없어서 반사가 안됩니다. 그리고 RayMarching 정밀도의 한계로 지터가 필수로 들어갈 수 밖에 없는데, 이게 픽셀게임에서는 더욱 티가 나는 것 같습니다. SSR로 구현한 Reflection ​ Planar Reflection SSR의 단점들이 너무 아쉬워서 Planar Reflection으로 다시 구현했습니다. 이 방법은 이름 그대로 평면에 한해서 밖에 반사를 시킬 수 없지만, jitter가 없는 깔끔한 반사가 가능하고 가려서 안보이는 물체도 반사 시킬 수 있습니다.
  • Concode
1
👍😲❤️
12
Floating Character Controller
프로젝트 x2는 높낮이가 있는 3D 지형을 쓰기 때문에 위 아래로 움직일 일이 많습니다. 3D 게임은 몇 번 개발해 본적이 있긴하지만, 그때 만들었던 3D 게임은, XZ 평면위에서 움직이는 거의 2D와 다들 바 없는 게임이였던 반면, 이번 프로젝트 x2는 반대로 2D 게임처럼 보이지만 더 높낮이를 적극 적으로 써서, 개발적으로 보자면 더 3D 게임스럽습니다. 문제 발생 이런 곳에서 움직으는 캐릭터를 조작하는 게임을 만들어 본 적은 없어서 막상 제작을 해보니 간단한 턱을 올라가는 것 부터 온갖 문제에 시달리게 됐습니다. 지형을 판단해 캐릭터가 턱을 올라가는 상황임을 파악하고 적절히 캐릭터의 상태와 애니를 처리하는 것부터 쉬운일이 아니였습니다. 그보다 큰 문제는, 갑자기 턱에 걸려 캐릭터가 의도치 않게 하늘위로 튕겨져 올라간다든지, 갑자기 어디 끼인다던지, 온갖 의도치 않는 상황들이 발생했습니다. 유니티가 제공해주는 물리 엔진 기능만을 전적으로 사용하는것은 방법이 아닐것 같은 생각이 들었습니다.​ 자료조사 그래서 자료를 조사하다가 찾아낸 키워드가 Flaoting Capsule Approch 입니다. 이 방법은 캡슐을 지면에 띄워서, 실제 충돌은 일으키지 않고, 지면과 콜라이더 사이를 일종의 스프링처럼 활용하는 방법입니다. 바닥과의 충돌 체크는 Raycast를 이용합니다. 점프가 있는 게임은 만들어본적이 없어서, 이런 방식으로도 구현할수 있구나! 하고 눈이 번쩍 떠졌는데, 플래포머를 만드는 분들한텐 익숙한 개념인지도 모르겠습니다. 자료 조사중에 이 방법의 구현을 자세히 설명한 영상을 찾게 되었습니다. Very Very Valet 이라는 게임에서 공유해준 영상입니다. 이 방식이 필요한 이유과, 구현의 원리, 코드도 대략 보여줍니다. ​​ 요구사항 이 영상을 보기전엔 사실 뭐가 필수적으로 구현되어야 되는지도 몰랐는데, 영상 덕택에 필요한 것들이 뭔가를 알게 된것도 큰 수확인것 같습니다. 대략 적으로 다음과 같은 것들이 요구됩니다. 이동 지형에 따른 이상 동작 방지 빠른 방향 전환 ​
  • Concode
👍🕴️
4
Fog of War
저희는 탐험이 주요 재미 포인트인 게임을 만들고 있습니다. 이런 종류의 게임에서 캐릭터가 맵을 이동할 때, 가보지 않은 곳이 다 화면에 보인다면, 맵을 돌아다니면서 탐험하는 몰입감이 떨어지게 됩니다. 모바일 버전은 화면이 작아서 덜하겠지만 PC라면 그 아쉬움이 클 것 같습니다. (집에갈고양의 PC버전 처럼요 ㅠㅠ) 그래서 이번 게임에서는, 스타크래프트나 롤처럼 처럼 내가 가보지 않는 곳은 화면에서 어둡게 보이도록 하는 기능을 개발하고자 합니다. 내가 있는 곳에서 내 시야가 닫는 범위 까지만 맵에서 밝아져야 합니다. Step자료 조사 이런 알고리즘은 통칭해서 Vision알고리즘이라고 하는 것 같은데, 타일 베이스 로그라이크 장르의 게임에서 오래전부터 연구되어온 주제로 아래 링크에 여러 알고리즘이 자세히 소개되어 있습니다. http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html 아래 두가지가 많이 쓰이는 것 같습니다. Ray casting Shadow casting 자료를 조사하다 한국 개발자 Keith님의 글을 발견했습니다. 유니티 에셋 스토어와 노션 페이지를 통해서 코드를 무료로 공개하고, 사용법도 영상으로 공개해 둬서 이 분의 코드와, 노션에 올려둔 레퍼런스들을 참고 삼아서 자체 제작을 시작했습니다. https://nonstop-marigold-de3.notion.site/Docs-AOS-Fog-of-War-v1-2-2d58922e8b4343498bca5ffdc9c97291 알고리즘은 이 개발자가 사용했던 Shadow Casting을 사용하기로 했습니다. 알고리즘은 아래 페이지에 자세히 소개되어 있는데, 라인바이 라인으로 따라가면서 어떻게 동작하는지 확인 가능합니다. https://www.albertford.com/shadowcasting/ Step컬러링으로 구현 위 Shadow casting 알고리즘은 구현이 짧기도 하고, 설명이 잘 되어 있어서 c#으로 포팅하는 것은 간단했습니다. 원본 소스에는 C#에는 없는 파이선의 유리수를 다루는 Fraction 클래스를 사용하는데 그냥 float로 해도 큰 문제는 없는 것 같습니다.
  • Concode
👍❤️
4
Systemic Game Design
체계적인 게임(Systemic Game)은 모든 개별 시스템이 서로 연결되어 영향을 줄 수 있도록 만들어진 게임입니다. 이 시스템에 대한 자세한 설명은 아래 링크의 영상에 자세히 설명되어 있습니다. 이 디자인 철학의 좋은 예는 Breath of the Wild 의 ‘비’ 메커니즘입니다 . 야생의 숨결 에서 비가 내리면 , 전체 게임 세계가 영향을 받습니다. 표면을 오르기가 더 어려우며 가시성이 영향을 받지만 Link의 발걸음 소리가 작아져 몰래 돌아다니기가 더 쉽습니다. 불이 지글거리고, NPC는 대피소로 달려가고, 금속 물체는 번개를 끌어당기고, 큰 빗물 웅덩이가 형성되지만 나중에 해가 뜨면 증발합니다. 게임의 날씨 시스템은 단순한 시각적 추가 요소가 아니라 게임 세계의 거의 모든 것에 영향을 미치는 필수적인 부분입니다. 종종 시스템 게임에서 이러한 서로 다른 시스템의 상호 작용은 예상치 못한 의도하지 않은 게임 플레이 시나리오로 이어집니다 (…) Systemic Game 설계 현재 작업중인 프로젝트 x2도, 이 디자인 철학을 많이 반영할 에정입니다. 하지만, 이 디자인 철학이 본격 적용된 게임이 나온지 얼마 되지 않아서 레퍼런스로 삼을 자료가 많지 않습니다. 서로 상호작용하게 되면, 오브젝트와 특정 상황에 대한 조합의 경우가 기하 급수적으로 늘어날 수 있습니다. 따라서 각 오브젝트가 특정 타 오브젝트나 사건을 개별적으로 인지하도록 구현하는 것은 좋은 접근이 아닙니다. 다행이, 위 영상에서 중요한 힌트를 알려줬습니다. 자극을 일반화 하고 오브젝트가 자극을 인지하게 한다. 자극(Stimulus)와 이에대한 반응(Response)은 어떤식으로 설계해야 할까, 고민을 하던차에 우리 몸이 자극과 이에 대해 반응을 하는 것이 이 모델과 비슷하지 않을까 생각이 들었고, 이에 대한 모델링은 이미 되어 있지 않을까 하는 생각이 들었습니다. 그래서 찾게된 자극 반응 모델입니다. Stimulus-Response https://ib.bioninja.com.au/standard-level/topic-6-human-physiology/65-neurons-and-synapses/stimulus-response.html 자극이 발생하면 다음과 같은 일련의 과정을 거처 자극이 처리됩니다. 자극 → 수용체 → 중추 신경계(CNS) → 효과기(Effector) → 반응 S-R 모델 구현 이제 구현만 남았습니다. 자극을 모델링하고, Receptor와 Effector, CNS를 모델링하면 됩니다. 설계와 구현이 쉽진 않아서 한번 구현한걸 통째로 엎고 다시 구현했습니다. 대략 다음과 같이 구현해봤습니다.
  • Concode
👍👏
5
Tilemap Editor
지난번에 글을 쓴 맵 에디터에는 꽤 많은 추가 구현이 있었습니다. 큰 피쳐들만 리스팅 해보면 다음과 같습니다. Inspector가 구현 Undo - Redo 기능추가 워터 타일의 추가 글로벌 조명 프리셋 구현 테스트 플레이 기능 추가 Inspector 구현 같은 오브젝트지만 조금씩 다른 값을 가져야 할 필요가 있습니다. 예를 들면 조명과 같은 경우엔, 조명에 따라 다른 밝기를 가질 수 있습니다. 오브젝트를 별도로 분리하는 방법도 있지만, 그렇게 되면 너무 많은 오브젝트가 생기면서 관리가 꽤 불편해질 수 있습니다. 그래서 단순히 오브젝트를 배치하는 것만이 아니라, 오브젝트의 속성을 편집해주는 기능이 필요합니다. 유니티에서 데이터를 저장할 클래스를 만들고 SerializedField를 붙여주는 것만으로 혹은 ScriptableObject를 만드는 것으로 따로 Inspector 를 위한 작업을 할 필요가 없지만, Play Mode에서 만들게 되면 유니티가 제공해주는 기능을 쓰지 못하고 직접 만들어야 합니다. 바퀴를 재발명하는 것 같은 기분에 이게 맞나 싶긴 하지만 꿋꿋이 해봅니다. 다행이 C#에는 Reflection기능이 이런 작업을 효과적으로 할 수 있을 정도로 강력합니다. 기본적인 방법은 지난 글에 적어뒀기 때문에 여기서는 실제로 어떤식으로 동작하는지만 보도록 하겠습니다. UnitValue 어트리뷰트와 인터페이스를 만들고 밸류를 저장할 클래스를 만들고 오브젝트를 배치하면, Inspector에서 오브젝트에 저장된 Value를 변집할 수 있습니다. Inspector의 UI는 클래스의 구조를 Reflection으로 파악후, 자동으로 InputField등이 렌더링 됩니다. 따라서 클래스의 구조가 변하거나 해도 UI를 별도로 수정해 줄 필요가 없습니다. (유니티가 하는 것처럼) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/374e9d4f-5ff8-441a-9d2c-0d515cd9df06/Untitled.png
  • Concode
Voxel2D Tile System
신작은 ‘집에갈고양’보다는 좀 더 퍼즐적인 요소가 강한 게임을 생각 하고 있습니다. 퍼즐 중 지형의 ‘높이’를 활용하는 것도 생각하고 있는데, 아쉽게도 유니티의 내장 타일 시스템은 높이값을 사용하기 어렵습니다. 원했던 타일시스템은 ‘케이던스 오브 하이랄’과 같은 지형 시스템이였습니다. 저희가 목표한 타일 시스템의 요구사항은 다음과 같습니다. 3D지만 2D처럼 보여야 함 게임중에 지형이 수정될 수 있도록 (채광이나 폭발로 인해) 성능이 좋아야 할것 편집이 쉬워야 할것 아쉽게도 에셋 스토에도 원하는 형태의 타일 시스템이 없어서, 저희만의 타일 맵 시스템을 직접 만들어보기로 했습니다. Voxel2D System “Terrain Height Map의 Voxel 버전”이 이 시스템의 핵심 목표 입니다. 완전 Voxel인 마인 크래프트와는 다르게 이 시스템은, 2D 이미지가 높이값을 가지는 시스템입니다. 따라서 중간에 떠 있는 지형은 없고, 모든 타일은 바닥부터 특정 높이를 가질 수 있습니다. 카메라는 45도 각도로 비추기 때문에, 앞면이 보이게 됩니다. 따라서 각각의 타일은 기본적으로 “윗면, 앞면”을 세트로 하고, 추가인 레이어도 가질 수 있게 했습니다. Chunk 지원 각각의 타일에 별도의 게임 오브젝트로 분리하고 콜라이더를 할당한다면, 추가 삭제는 편하겠지만 너무 많은 오브젝트가 화면에 만들어지면서 드로우콜이 늘어나고 너무 많은 콜라이더로 인한 성능 문제가 생길 수 있습니다. 반대로 너무 많이 묶는다면, 맵의 일부분만 변경하려해도 전부를 다시 계산해야 하고, Occlusion Culling이 동작하지 않는 문제가 생깁니다. 따라서 맵을 일부 구간으로 묶어서 Chunk 단위로 한꺼번에 관리를 해주는 것이 좋습니다. 저희는 8x8 크기의 Chunk로 타일맵을 분할해 관리하기로 했습니다. Tileset Wang tile은, 수학자 Hao Wang에 의해 1961년에 제안된, 사각형 타일을 인접한 이웃과 매치하게 배치하는 시스템에 대한 내용입니다. 자세한 내용은 아래를 참고해주세요. Wang tileset: http://www.cr31.co.uk/stagecast/wang/2corn.html
  • Concode
4
👍😍
6