[게임만들기 ④] 1인 게임 개발에 한 번 도전해보았습니다 - 배경 및 스테이지 설계편

기획기사 | 윤서호 기자 | 댓글: 22개 |



"잠시 손 놨더니 맥이 끊어져 버렸습니다."

아마 본업이 따로 있는 상태에서 1인 게임 개발을 진행하는 분들이라면 여러 번 느껴보셨을 겁니다. 본업이 바빠지면 부득이하게 잠시 개발이 멈춰질 때가 있는데, 그 후에 다시 작업에 들어가면 흐름이 끊겨서 어색해지는 그 느낌 말이죠. 물론 베테랑이거나, 1인 게임 개발 경력이 오래 됐다면 금방 적응하고 다시 작업에 들어갈 수 있을 겁니다. 하지만 저처럼 게임 개발 경력이 거의 없는 초짜에게는 작업의 흐름이 한 번 끊겨버린 것만으로도 치명적이죠. "뭘 해야 하더라? 뭘 어떻게 해야 하지?"라는 생각이 작업을 계속 방해하기 때문이죠.

특히나 앞으로 남은 작업이, 자신이 혼자서 해내기엔 어려운 작업이면 더욱 그렇습니다. 전편에 언급했던 것처럼 저는 게임의 기획이나 세계관을 짤 수는 있고, 캐릭터 디자인과 애니메이션까지는 어설프게나마 소화해낼 수 있지만 그 외의 분야는 경험이 없었기 때문이죠. 그래서 배경과 나머지 부분은 필연적으로 다른 사람이 만든 에셋을 활용해야 하는데, 이 부분에서 막혀버렸던 게 패착이었습니다.



▲ 2년 전에 그렸던 미완성작이지만, 지금 실력도 이것과 별 차이는 없을 정도입니다

배경은 우리나라의 도시의 느낌이 날 수 있는 타일맵, 혹은 2D 에셋을 필요로 했는데 그런 에셋은 구하기가 어려웠습니다. 아무래도 그런 배경을 사용하는 게임들이 적다보니, 에셋 역시도 적을 수밖에 없던 것이죠. 그래서 기본 지식은 알고 있으니 '만들어볼까?'라고 생각은 했지만, 이론과 실제는 달랐다는 것만 뼈저리게 느꼈습니다.

이 부분에 대해서는 추후에 설명하기로 하겠습니다. 어쨌든 결국 배경 작업에서 자꾸 지지부진한 나머지, 갈피를 못 잡고 방황하게 됐습니다. 뿐만 아니라 기본으로 짜둔 코드도 수정을 몇 번 가하니까 버그만 나오는, 그야말로 개발자 입장에서는 머리를 쥐어뜯을 수밖에 없는 상황에 봉착해버렸죠. 코딩을 대강 알고 있을 뿐 직접 코드를 만들 줄 모르다보니, 한계가 올 수밖에 없던 것이죠.

그런 상황이다보니 부득이하게 또 기획을 수정하고, 가능한 한도 내에서 할 수 있는 것들을 처리해나가야 했습니다. 서문이 길어졌습니다만, 이번에는 '제 13차원'에서 어떻게 스테이지를 설계해나갔는지, 현 단계에 대해서 좀 더 설명해나가고자 합니다. 또 미리 말씀드리는 부분이지만, 이번 편부터는 다음에 어떤 테마로 글을 쓰겠다 미리 예고하기가 어렵습니다. 제 역량이 미치지 못해서 막히는 부분은, 부득이하게 스킵할 수밖에 없다는 걸 절실히 느꼈거든요.



▲ 결국 배경 문제는 차순위로 하고, 스테이지 설계를 최우선으로 했습니다



■ 타일맵을 교체하고, 스테이지를 설계하다

타일맵은 2D 게임 개발에 관심이 있는 분에겐 딱히 설명할 필요가 없을 정도로 많이 사용되고 있는 기법입니다. 모르는 분들을 위해서 스타크래프트 유즈맵을 예로 설명을 드리면, 배경 하나하나를 그리거나 하지 않고 지형 팔레트나 그 외 다양한 팔레트에 사전에 작업해둔 에셋들을 올려놓고 그것들을 배치하는 것만으로도 맵, 배경, 혹은 지형이 완성될 수 있도록 하는 방식이죠.



▲ 스타크래프트 유즈맵 에디터의 타일셋을 생각하면 이해하기 편합니다

지난 번에 이미 타일맵으로 스테이지를 대강 만들어낸 모습을 보여드린 적이 있습니다. 그리고 타일맵을 단순히 배치하기만 해서는 캐릭터가 그 위에서 걷거나, 움직이거나 하지 못한다는 것도 보여드렸죠. 게임에서는 물리법칙의 적용 여부, 혹은 충돌 여부를 개발자가 모두 지정해줄 필요가 있습니다. 배경에 사용되는 것들도 마찬가지죠. 그냥 단순히 지나가는 배경으로 둘 것이냐, 혹은 플레이어에게 영향을 미치느냐에 따라서 세팅이 달라지죠.

타일맵으로 바닥을 깔 때면 Tilemap Collider2D를 활용하고, 여기에 Composite Collider 2D까지 같이 체크해서 타일맵을 깔 때마다 Collider가 자동으로 생성되게 하는 방식을 취합니다. 전에 샘플 타일맵을 골라서 대강 만든 스테이지도 그런 식으로 제작에 들어갔었죠.

그렇지만 그 샘플 타일맵을 적용했을 때는, 일부 구간에서 점프가 안 된다는 난점이 존재했습니다. 뿐만 아니라 걷는 동작도 안 나오는 문제도 발생했고요 이 부분은 사실 충돌 문제, 구조의 문제 때문이긴 했습니다. 무언가 거창한 것처럼 보이지만, 비유로 설명하면 굉장히 단순한 문제입니다. 점프와 걷는 동작을 하기 위해서는 먼저 바닥을 발로 디뎌야 하죠. 즉 플레이어의 Collider와 타일맵의 Collider가 온전히 접촉을 해야 비로소 행동이 이어집니다.



▲ Collider와 캐릭터 하단에 설치한 groundCheck이 온전히 닿지 않아서 생긴 참사.gif

여기에 보통 'groundCheck'라고 일컬어지는 것을 많이 사용하곤 합니다. 간단히 말하자면 지금 플레이어가 땅에 착지해 있는 상태라는 것을 보여주기 위한 표시라고 보면 되겠습니다. 제가 처음에 구했던 타일맵은 크기 때문에 중간중간 공백이 생겨서 Collider끼리 온전한 접촉이 일어나지 않고, groundCheck도 지면과 닿지 않기 때문에 제대로 애니메이터가 재생을 하지 않은 것이죠.

그래서 임시로 사용할 타일맵도 바꿨습니다. 콘크리트, 아스팔트 느낌이 나는 타일맵을 최우선적으로 찾다가 대강 회색톤인 타일맵 중 사이즈가 맞는 것을 찾아서 우선 적용하고, 오류가 해결되는지 여부부터 체크했죠. 그렇게 바꾸니까 달리다가 점프가 안 되는 현상은 해결했습니다. 물론 테스트 과정에서 이동-점프, 공격-점프, 이동-공격-점프-점프공격 애니메이터 간의 연결이 매끄럽지 않아서 동작이 부자연스러운 게 눈에 띄긴 합니다. 그 부분은 타일맵 작업과 별개로 애니메이터의 트랜지션과 애니메이터의 재생순서, 시작 타임 등을 세부적으로 설정해나가야 하는 작업이고, 적과의 합도 맞춰야 하는 부분이라 그때 가서 수정할 예정입니다.



▲ 타일맵을 바꾼 뒤로는 애니메이션의 흐름이 비교적 자연스러워졌습니다

스테이지 같은 경우에는 이미 전편에서 세분화를 하고, 기획을 다시 했다고 언급했었습니다. 단순히 도시라고 하면 너무 큰 범위이기 때문에 학원가, 아파트 단지, 번화가 이렇게 구역을 나눠서 설계해야 했죠. 그런 뒤에 각 파트에 맞는 테마의 에셋을 찾아나가는 작업을 우선시했지만, 지금은 일단 '최소 2D 횡스크롤 플랫포머로서 플레이할 수 있느냐'에 집중해서 스테이지를 설계해나갔습니다.

횡스크롤 플랫포머의 가장 기본적인 액션 단위는 이동, 점프, 공격입니다. 이 세 가지를 잘 조합해서 난관을 극복하는 것이 플랫포머의 꽃이죠. 반대로 플레이하면서 이 세 가지를 활용해서 클리어하지 못하는 레벨 디자인으로 만들어버리면 이도저도 아닌 것이 된다는 의미기도 합니다. 이를 파악하기 위해서는 스테이지를 샘플로 만들고, 캐릭터가 그 스테이지 위에서 제대로 노닐 수 있는지를 확인하는 작업을 거쳐야 했죠.



■ 씬의 분할과 구성, 그리고 스테이지의 재설계

스테이지, 배경을 구성할 때 그 겉모습 뿐만 아니라, 씬과 시퀀스를 어떤 식으로 구성해나갈지도 중요한 부분입니다. 마리오나 록맨에서 예를 들었던 것처럼, 한 스테이지를 클리어하고 그 맵 그대로 이어지는 것이 아니라 다른 맵, 다른 씬으로 이어지듯이 말이죠.

그것에 대한 설계는 이미 사전에 어느 정도 기획이 된 부분이었습니다. 스테이지 1의 구성은 총 네 개의 씬으로 구성될 예정이라서 씬을 먼저 네 개 만들고, 각 씬의 흐름에 맞춰서 스테이지를 구성해나갔죠. 처음에는 지상에서 지하로 내려가고, 잔해들을 부수고 넘어간다는 컨셉이기 때문에 곳곳에 점프할 곳을 마련해두고, 플레이어가 깨부술 블록 등도 마련해두었죠. 그 외에 스테이지도 캐릭터의 동선을 짜고, 그에 맞춰서 타일맵을 세팅했습니다.



▲ 타이틀 화면까지 포함해서 총 5개의 씬을 넣었습니다.
참고로 빌드 세팅에서 씬을 넣지 않으면, 씬 전환이 일어나지 않습니다

그 다음에 우선순위를 잘못 짜서 바로 백그라운드에 쓰일 타일셋을 만들거나 찾아보다가 흐름이 끊어지고, 또 출장 등 여러 가지 일이 겹치면서 결국 몇 달 동안 손을 제대로 못 대는 불상사가 발생해버렸죠. 뿐만 아니라 스테이지 테스트를 위해서는 이단 점프가 필요하다고 생각해서 코드를 찾아서 적용했는데, 이 코드가 기존 코드와 충돌하는 바람에 이도저도 못하는 일이 발생해버렸습니다. 그러다가 지스타 유니티 카페에서 오지현 에반젤리스트에게 솔루션을 받은 뒤에 좀 생각이 바뀌었죠. 이단 점프 없어도 된다, 라는 것이죠.

그것보다는 지금의 캐릭터 움직임을 좀 더 테스트하고, 이걸 좀 더 최적화한 상태에서 스테이지를 설계하는 것이 옳다고 느꼈죠. 앞서 말씀드린 것처럼 애니메이션과 애니메이터도 손을 봐야 하지만, 그것을 설정하기 위해서는 캐릭터의 이동 속도나 점프 높이를 미리 정해야 할 필요가 있습니다. 흐름이 자연스럽게 이어지기 위해서는 어느 정도 빠르기로 움직이고, 체공 시간이 어느 정도인지를 파악해야 했기 때문이죠.

초기에 이 부분은 신경쓰지 않고 단순히 유니티 자습서 중 Creating a Basic Platformer Game의 컨트롤러 스크립트에 있는 수치를 거의 그대로 썼었습니다. 그러다가 조금 느리다는 생각이 들어서 일부분 수정을 했고, 그 수치를 기반해서 스테이지를 구성했죠. 이 방식은 이번에도 동일하게 진행했습니다. 기존에 이동하는 힘에 300, 최고 속도에 5, 점프력에 400이라고 줬던 것을 조정 끝에 410, 10, 550으로 변경한 것이죠. 이 수치 자체에 큰 의미가 있다기보다는, 캐릭터의 움직임을 자연스럽게, 혹은 게임 진행에 원활하도록 만들기 위해서 캐릭터에게 가해지는 힘이나 캐릭터의 질량을 바꾸어나갔다고 보면 되겠습니다.



▲ 스크립트에서 변수에 임의로 정해둔 수치를



▲ 엔진 내에서 테스트하면서 계속 바꿔서 적용했습니다

여기에 맞춰서 스테이지를 재설계하는 과정 자체는 간단했습니다. 일단 타일맵을 세팅하고, 캐릭터를 일일이 움직여보면서 테스트하고 수정하는 것이 전부였기 때문이죠. 그리고 씬과 씬을 전환하는 과정도 테스트를 들어가야 했습니다.



▲ 이렇게 직접 엔진 내에서 플레이해보고, 무언가 부족한 부분이 있으면 수정해나갔습니다

씬과 씬을 전환하는 코드는 일반적으로 메뉴창에서 버튼을 클릭해서 다른 씬으로 가는 예시가 많이 나옵니다. 그 코드는 횡스크롤에서 사용하기는 조금 어렵습니다. 횡스크롤 스테이지에서는 일단 플레이어가 특정 오브젝트와 충돌, 혹은 상호작용이 일어나야 씬이 전환하도록 설계가 되어있기 때문이죠.

그래서 제가 쓴 코드를 간단하게 공유해보겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneChange : MonoBehaviour
{
GameObject player;
[SerializeField] private string Stage0102;

void Start ()
{
player = GameObject.FindGameObjectWithTag("Player");
}

void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject == player)
{
SceneManager.LoadScene("Stage0102");
}
}

코드를 읽을 줄은 알지만 전공이 아닌 만큼, 자세하게 설명하기는 어렵습니다. 다만 간단하게 보충 설명하자면 사전에 "Player"라는 태그를 만들어야 합니다. FindGameObjectWithTag라는 말 뜻 그대로 태그명을 토대로 오브젝트를 찾아가는 것이거든요. 괄호와 큰따옴표 안에 있는 것은 제가 사전에 미리 지정해둔 태그명이고, 채림에게 이 태그를 부여해두었습니다.

그 다음 단계는 이 태그를 갖고 있는 오브젝트가 충돌했을 때를 상정해야 합니다. 즉 다른 Collider 2D와 충돌했을 때, 그 오브젝트가 미리 정해둔 player의 조건과 동일할 경우에만 지정된 씬으로 이동할 수 있도록 하는 것이죠.




프로그래밍을 배울 때 반환한다, 선언한다 이런 말이 자체도 일반적으로 활용되는 것과는 조금 다른 의미를 갖고 있습니다. 그래서 유니티 매뉴얼에 해당 코드들을 검색했을 때 나오는 설명을 이해하기는 사실 좀 어렵고, 이해했더라도 막상 그걸 쉽게 풀어서 이야기하기가 힘듭니다. 프로그래밍 수업 때를 떠올려보면, 처음에는 저 말의 뜻을 대강 설명하셨다가 나중에 가서는 그냥 저 말을 그대로 활용했거든요.

그 정도로 프로그래밍에 대한 이해가 부족한 상황에서 코드를 얼기설기 만들어가고, 체크해서 다듬어갈 수 있는 이유는 딱 한 가지입니다. "기계는 명령 받은 것만 처리한다"라는 것을 인식하고 있기 때문이죠. 사람들은 말하지 않아도 감으로, 맥락으로 이해를 하지만 프로그램은 그렇지 않습니다. 종종 레퍼런스라는 개념을 언급하긴 하는데, 그 레퍼런스도 정확하게 무엇인지 지정을 하지 않으면 인식하지 못하죠. 혹은 그 레퍼런스의 데이터가 불완전해서 읽을 수 없으면 불러올 수도 없습니다.

게다가 우리가 말하는 '플레이어'라는 것을 곧이곧대로 써봤자 프로그램은 이해를 못합니다. 이를 프로그램이 알아들을 수 있도록 변수를 지정하고, 이를 따로 다 정의해줘야 비로소 이해를 하는 셈이죠. 제 경우에는 그걸 어떻게 정의해야 하는지, 또 원하는 조건을 만들기 위해서 어떤 함수를 만들어야 하는지는 잘 모릅니다. 다만 이런 작업을 해두지 않으면 프로그램이 돌아가지 않는다는 건 알고 있죠.

즉 어떤 일이 일어나기 위해서는 사전에 조건을 만들고, 그 조건에 엮여있는 오브젝트들을 찾아서 정의하는 기초적인 작업은 염두에 두고 있는 셈입니다. 그리고 오류가 나면 어디에서 어떤 부분이 비었을까 혹은 어떤 부분에서 잘못됐을까 계속 고민하면서 찾는 것은 알고 있어서, 어떻게든 꾸역꾸역 참고할 거리를 찾으면서 코드를 맞춰가는 것이죠.

스테이지를 이동할 때는 플레이어가 특정 오브젝트, 혹은 특정 공간에 들어왔을 때를 조건으로 삼았습니다. 그 조건을 '충돌'로 구현했고, 다른 오브젝트가 아닌 "Player"란 태그를 갖고 있는 오브젝트와 충돌했을 때만 씬을 전환할 수 있어야 한다는 조건을 추가로 부가한 셈이죠. 이를 활용하기 위해서는 사전에 태그를 구분해뒀어야 하는데, 이 작업은 미리 해두었습니다. 그리고 어느 씬으로 이동할지에 대해서도 Stage0102라고 사전에 정의를 해두었죠.



▲ 사전에 Player 태그를 만들어두고, 그걸로 플레이어를 인식하도록 세팅해두었습니다

단순 이동에 관련된 부분은 그렇게 어렵지 않지만. 나중에 적을 스테이지에 배치할 때는 좀 더 다양한 조건이 추가가 될 필요가 있습니다. 그리고 그 조건에 따라서 어떤 일이 벌어지는지, 좀 더 세부적으로 기획한 다음에 그에 맞춰서 코드를 짜맞춰나가야 하죠. 그 외에도 다른 오브젝트를 시각적으로 잘 구분하기 위해서는 에셋도 좀 더 구색을 갖출 필요가 있지만, 이 부분은 임시방편으로 만들어두고 코드를 테스트한 뒤, 에셋을 구해서 수정할 예정입니다.



■ 앞으로 해야 할 과제 - 에셋 마련, 실제 플레이에 맞춘 코드 및 애니메이션 수정, 빌드 테스트

"신은 디테일에 있다"

창작을 해본 사람이라면 이 속담을 아마 여러 번 들어보셨을 겁니다. 무언가를 만들 때 완성도를 높이려면 세부적인 것이 중요하다는 의미죠. 불쾌한 골짜기를 떠올려보면 이해하기가 쉬울 겁니다. 다 괜찮아보이다가도 어느 한 부분, 혹은 일부가 이상하면 그 좋은 것들이 다 상쇄되어버리는 경우가 왕왕 있기 때문이죠.



▲ 용례가 다르긴 하지만, 어쨌든 디테일이 이상한 것에 사람은 꽤 민감한 편입니다

이런 디테일 부분은 앞에서도 여러 번 언급했지만, 게이머의 입장에서 보면 일일이 설명할 필요가 없는 부분입니다. 그렇지만 제작자의 입장에서 보면, 특히 1인 개발을 하는 입장에서 보면 가장 거슬리는 부분이죠. 모든 디테일을 혼자서 다 처리할 수 있다면 조금은 나을 수 있겠지만, 그걸 혼자 다 할 수 없어서 외부 에셋을 사용해야 할 때는 골치가 더 아프기도 합니다. 원하는 스타일의 에셋이 없으면 어떻게 해야 하나 막막해지기도 하죠.

사실 에셋을 넣는 것 자체는 그리 어렵지는 않습니다. 사운드 같은 경우에는 오디오소스를 넣는 코드만 따로 넣은 뒤에, 거기에 미리 준비해둔 에셋을 집어넣으면 되죠. 루프 등 기본적인 것도 엔진 내에서 세팅이 가능하기 때문에 에셋만 구해두면 크게 문제가 될 사항은 없습니다. 특수 효과도 마찬가지입니다. 문제는 그걸 어떻게 갖출까, 하는 부분입니다.






▲ 스크립트에 변수로 AudioClip과 AudioSource를 정리해두고



▲ 엔진에서 해당 파트에 맞는 리소스를 집어넣으면 활용할 수 있습니다

"이걸 직접 만들까? 아니면 좀 더 찾아볼까?" 이런 고민 때문에 갈팡질팡하기도 합니다. 그러다가 원하는 에셋을 찾아도 만족스럽지 못할 때가 있습니다. "이런 부분은 좀 수정했으면 좋을 것 같은데 어떻게 안 되려나?" 이런 생각들이 들 때가 한두 번이 아니었거든요. 여기에 배경과 스테이지 작업을 우선 진행하고 있기 때문에 그와 관련된 에셋을 많이 언급했지만, 앞으로는 특수 효과와 사운드 에셋까지도 고려할 필요가 있죠. 그걸 확보한 다음에도 컨셉, 혹은 게임의 스타일에 맞춰서 편집하거나 혹은 배치하는 것도 생각은 해두고 있지만, 일단은 최대한 많은 에셋을 확보하는 것을 최우선으로 잡고 있습니다.

그게 불가능하다면 최후의 수단으로, 에셋에 맞춰서 게임을 변화시키는 극단적인 방법도 있습니다. 아니면 컨셉을 살짝 손을 보던가, 편법을 써서 '그냥 그런가보다'라고 납득이 될 수 있게 만드는 방법도 있겠죠. 아직 씬에 넣을 인게임 연출, 즉 스크립트나 캔버스도 대강 설계만 하고 작업은 들어가지 않았기 때문에 이 부분을 만들어가면서 아마 스토리나 컨셉 부분에서 보충을 해나가는 방법을 쓰게 될 것 같습니다. 물론 시나리오는 스킵되는 경우가 상당히 많기 때문에, 이 방법이 그리 효과적이진 않을 것 같다는 생각이 들긴 하지만요.

그리고 지금 테스트를 위해서 엉성하게 만들어둔 애니메이션이나 코드도, 점차 실제 플레이 테스트에 맞춰서 수정을 해야 할 필요가 있기도 합니다. 특히나 일반 공격을 구현하기 위해서 만들었던 것들을 최우선적으로 고쳐야 하는 상황입니다. 일반적으로 근접 공격을 구현할 때 빈 오브젝트를 자식으로 두고 Collider를 공격 범위만큼 만들어서 히트박스를 만듭니다. 그리고 여기에 IsTrigger를 걸어둔 상태에서 공격키를 누르면 공격이 되도록 코드를 짜두게 되죠.



▲ 히트박스를 만들고



▲ 이 히트박스가 공격 버튼을 눌렀을 때만 적용이 되도록 코드를 짰습니다

일단 제가 참고한 코드는 유튜브에 올라온 GucioDevs의 Unity 5 2D Platformer Tutorial - Part 20 - Melee Attacking입니다. 이걸 일단 컨트롤러 코드 중간에 붙여넣고, 새로 어택 컨트롤러라는 스크립트를 짜면서 공격 판정을 만들어냈죠. 그렇지만 코드를 짜집기할 때 언제나 그렇듯, 문제가 발생해버렸습니다. GucioDevs가 구현한 밀리어택은 굉장히 짧게 반복되기 때문에 히트박스가 빠르게 활성화가 되도 상관이 없습니다. 그렇지만 채림의 대검은 그렇지 않다보니 모션과 공격 판정이 일치가 안 되는 문제가 생겨버렸죠.

▲ 코드 작성할 때 참고한 GucioDevs: Unity 5 2D Platformer Tutorial - Part 20 - Melee Attacking



▲ 일격만 날린 거지만 시스템에서는 수도 없이 많은 참격이 있었다고 인식해버렸습니다.



▲ 그리고 누르자마자 바로 활성화가 되어버려서 모션과 일치하지도 않는 불상사가 발생했죠

이 문제도 해결하면서 아직 구현하지 못한 스킬이나, 그리고 직접 게임플레이할 때 문제가 되는 모션과 히트박스 수정도 필요합니다. 패턴을 점프 어택으로 피하면서 공격하는 것도 생각해두었는데, 현재 점프 어택으로는 하단에 있는 적을 제대로 공격할 수가 없죠. 그래서 모션을 수정하고, 그 모션에 맞게 히트박스를 만들고 공격 판정을 부여해가야 합니다. 물론 각 동작 간의 연결을 좀 더 자연스럽게 하기 위해서 애니메이터도 수정하고, 애니메이션도 계속 다듬어가야 하죠.



▲ 최초 테스트용으로 간단히 만들었던 애니메이션이라 수정 및 보완이 필요합니다

그간 엔진 내에서만 테스트했지만, 빌드가 잘 돌아가나 중간중간 테스트도 필요하죠. 특히나 처음에 안드로이드용으로 만든다고 했었는데, 그걸 까맣게 잊고 있던 터라 빌드 테스트를 하면서 수정하는 과정도 필요할 것 같습니다.

작업이 늦어지는 데다가, 앞으로 넘어야 할 산도 많기 때문에 원래 3스테이지 정도로 기획했던 것을 1스테이지로 줄여나갈 예정입니다. 제 13차원을 처음 생각했을 때 담고자 했던 이야기를 3분의 1 정도로 줄여야 하는 셈이고, "과연 이걸 게임이라고 할 수 있을까?"라고 싶은 마음도 들고 있긴 합니다.

그렇지만 개발을 진행하면서 제 한계를 다시 한 번 느꼈고, 이것을 단기간에 극복하기엔 무리가 있었습니다. 지금 제 자신을 평가하자면, 코드도 모르고, 그림도 반쪽짜리에 눈은 이상하게 높은 데다가 취향도 특이한, 그야말로 "같이 개발하면 안 되겠다" 싶은 전형적인 케이스거든요. 그러니 혼자 해야 하는데 혼자 역량이 안 되니까 막혀버리는, 골치 아픈 상황에 처해있다고 보면 되겠습니다.

아마 이 작업은 혼자 해야 하는데 역량이 부족해서 결국 목표한 것을 그대로 이루지 못하고 적절히 타협해서 다운그레이드를 진행해야 하는, 전형적인 쓸쓸한 결말이 기다리고 있을 겁니다. 그런 결말에서 최대한 멀리 떨어지기 위해서, 내년에는 좀 더 노력해야 하겠죠. 부족한 역량으로 만들어낸 것들, 혹은 이곳저곳에서 얻은 것들을 이리저리 끼워맞추고 편법으로 메워나가겠지만, 다음 번에 뵐 때는 한 개의 스테이지긴 하지만 조금 더 그럴 듯한 횡스크롤 게임의 모양새로 찾아올 수 있도록 하겠습니다.





※그래서 요약하자면?

1) 잠시 개발을 중단했다가 다시 시작해서 흐름이 끊어졌고, 직접 처리하기 어려운 파트를 진행해야 했기 때문에 작업이 늦어졌다. 그 작업은 계속 진행하지만, 앞으로 어떤 작업을 소개해나갈지는 역량 문제 때문에 미리 예고하기 어렵다.

2) 타일맵 에셋을 구하고 여기에 Collider 2D를 넣은 뒤에 구상했던 대로 스테이지를 만들어나가는 작업을 이미 거쳤었다. 그렇지만 저번에 구했던 타일맵 에셋은 사이즈가 작아서 채림의 groundCheck과 온전히 접촉하지 못했다. 그래서 중간중간 점프가 안 되는 구간이 있었고, 그래서 타일맵 에셋을 교체했다

3) 중간중간 점프가 안 되는 문제는 해결했지만 동작 연결이 부자연스러운 문제는 지속적으로 보였다. 이 부분은 애니메이터의 트랜지션, 재생순서, 시간 등을 하나하나 수정해나갈 계획이다.

4) 횡스크롤 플랫포머의 가장 기본적인 액션 단위는 이동, 점프, 공격이다. 이 세 가지를 조합해서 난관을 어떻게 극복해나가느냐가 플랫포머의 핵심 포인트다. 이 연결이 스테이지에서 잘 매끄럽게 연계되고, 또 스테이지가 이 액션에 맞춰서 잘 설계가 됐는지 파악하기 위해서 계속 테스트를 하고 수정을 해야 했다.

5) 스테이지 1은 네 개의 씬으로 구성이 되어있다. 각 씬별로 테마는 미리 상정해두었으며, 그에 맞춰서 스테이지맵을 만들어나갔다. 최초에는 이단 점프를 활용하는 맵을 생각했지만, 이단 점프가 횡스크롤에서 필수 조건은 아니라고 생각해서 그 부분을 제외하고 다시 설계했다.

6) 좀 더 플레이를 매끄럽게 진행할 수 있도록 캐릭터의 움직임을 최적화했다. 애니메이터나 애니메이션은 현 단계에서 건드리지 않고, 코드를 일부 변경했다. 이 과정은 Chaerim Controller 코드에 적어둔 캐릭터가 이동할 때 가해지는 힘, 캐릭터의 최대 속도, 점프력 수치를 변경하고 테스트를 하는 식으로 진행했다.

7) 적정 수치를 입력한 뒤에는 타일맵을 다시 깔고, 실제 플레이 테스트를 해보면서 레벨디자인 체크를 했다. 특정 오브젝트에 사용될 타일맵들은 아직 구현하지 못했기 때문에 임시방편으로 구해둔 타일맵을 설치해두고, 코드를 짜서 적용해뒀다.

8) 씬과 씬을 전환하는 코드는, 일반적으로는 메뉴창에서 버튼을 클릭하면 다른 씬으로 이동하는 방식으로 많이 예제가 나온다. 그래서 횡스크롤에 적합한 코드를 따로 구축해나가야 했다. 그 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneChange : MonoBehaviour
{
GameObject player;
[SerializeField] private string Stage0102;

void Start ()
{
player = GameObject.FindGameObjectWithTag("Player");
}

void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject == player)
{
SceneManager.LoadScene("Stage0102");
}
}

9) 코드를 이리저리 끼워맞추거나 작성할 때 유의해야 할 점은, "기계는 명령 받은 것만 처리한다"는 점이다. 즉 특정 사건이 발생하는 조건, 그리고 그 조건에 들어가야 할 오브젝트에 대한 사전 정의가 하나라도 빠지면 안 된다. 그냥 플레이어라고 적으면 프로그램은 모른다. 그 플레이어를 어떻게 프로그램이 구분할 수 있는지 조건, 혹은 변수 선언을 해주어야 한다.

10) 이번 코드는 2D 오브젝트가 충돌이 일어났을 때, 그 2D 오브젝트가 "Player"라는 태그를 갖고 있을 경우에 씬이 전환되도록 짰다. 태그는 사전에 구분해두었으며, 어떤 씬으로 넘어갈지도 지정해두었다.

11) 게이머였을 때는 당연히 있어야 한다고 여기는 것들이, 제작자 입장에서는 하나하나 구축해나가야하는 것들이다. 스테이지를 만들 때 최우선적으로 보게 되는 배경 및 타일맵에 우선 신경을 썼지만, 앞으로는 특수 효과 및 사운드도 생각을 해야 한다. 그것도 게임의 컨셉과 스타일에 맞는 것을 구하거나, 혹은 편집해서 배치해야 한다. 정 안 되면, 효과적이지는 않지만 스타일에 맞춰서 게임을 변화시키는 극단적인 방법을 취하거나 아니면 스크립트로 납득을 시켜버리는 방법도 있을 수 있다.

12) 현재까지는 캐릭터가 잘 움직이나, 스테이지를 잘 건너가나에만 집중했지만 앞으로는 실제 플레이를 쾌적하게 할 수 있도록 테스트를 좀 더 진행하고, 그에 맞춰서 코드와 애니메이션을 수정할 계획이다. 현 상황에서는 히트박스가 너무 빠르게 활성화되는 것 때문에 모션과 공격 판정이 일치가 안 되는 등 문제가 발생했다. 또한 점프 공격 모션이나 히트박스가 현 단계에서는 플레이할 때 문제가 되기 때문에, 이 부분을 수정해야 한다.

13) 빌드 테스트도 필요하다. 특히나 최초 안드로이드용으로 만든다고 했는데, 이걸 잊고서 PC용으로만 테스트를 했기 때문에 여기에 맞춰서 수정하는 과정도 필요하다.

14) 스테이지는 최초 3개를 기획했지만, 현 단계에서 역량 부족으로 스테이지는 한 개로만 만들 예정이다. 역량 부족으로 인해서 최초 목표했던 것을 적절히 타협해서 다운그레이드된 결말을 보여주게 되겠지만, 한 개의 스테이지이긴 해도 조금 더 그럴듯해진 횡스크롤 게임의 모양새로 만들어나가는 데에 집중하고자 한다.

댓글

새로고침
새로고침

기사 목록

1 2 3 4 5
검색