Ctrl-Z는 두 개의 이어진 맵과 시간 역행이라는 독특한 메커니즘을 사용한 인디 플랫포머 게임입니다.
박준현(고려대학교 20)
한관희(한양대학교 18)
홍성준(KAIST 18)
- 2D 퍼즐 플랫포머 장르
- 한 레벨은 상단과 하단의 두 부분으로 나뉘며, 상단 맵을 플레이할 때에 하단 맵에 끼칠 영향을 고려하여 신중한 선택을 내려야 합니다.
- 죽음의 위기에 처하거나, 퍼즐이 해결 불가능한 상태가 되었을 때에는 시간을 되돌려 다시 도전할 수 있습니다.
- Framework: Unity 2021.3.6f1
- Language: C#
- IDE: Visual Studio Code
- Asset editor: Aseprite
- A와 D키를 이용해 좌우로 이동할 수 있습니다.
- 스페이스바를 이용해 점프할 수 있습니다.
- 상단 맵에서 S키를 누를 시 하단 맵을 확인할 수 있습니다.
- 하단 맵에서 W키를 누를 시 상단 맵을 확인할 수 있습니다.
- R키를 누르면 시간을 되돌려 상단 맵의 시작 지점으로 되돌아갈 수 있습니다.
- 플랫포머 장르에서는 조작감이 게임의 완성도에 있어 매우 큰 역할을 한다고 생각합니다. 이에 조작감을 개선하기 위해 플레이어의 움직임을 fine-tuning하기 위해 많은 시간을 투자하였습니다.
- 물리 엔진에 기반하여 움직임을 구현하였습니다.
- 공중에서 점프하는 것을 방지하기 위해서 ray-casting을 사용하였습니다. 플레이어를 기준으로 y-axis의 음의 방향으로 ray를 cast해 땅인지를 판단하고, 이에 기초해 점프를 허용 또는 방지합니다.
- 더 세밀한 디테일로는 coyote time과 jump buffering을 구현하였습니다.
- Coyote time은 플레이어가 지표면에서 떨어진 후 잠깐 동안의 시간에도 점프가 가능하도록 하는 메커니즘입니다. 이를 통해 지표면에서 떨어지기 직전의 순간에 점프하는 것을 보다 쉽게 함으로써 조작감을 개선합니다.
- Jump buffering은 반대로, 플레이어가 지표면에 도달하기 직전에 입력한 점프 명령이 무시되지 않고 땅에 닿았을 때 다시 점프를 수행해주는 것을 말합니다. 이를 통해 키 입력을 했음에도 반영되지 않았다고 느껴질 만한 요소를 최소화하였습니다.
- Ctrl-Z를 제작하며 중요하게 여겼던 요소 중 하나는 단순히 코딩에만 초점을 두는 것이 아니라, 게임 개발의 전 과정을 경험해보고 기여해보고 싶다는 것이었습니다. 그리고 이에 있어 게임을 구성하는 모든 픽셀 아트 에셋을 직접 제작하였다는 사실은 저희에게 큰 의미가 있습니다.
- 픽셀 아트 제작에는 Aseprite를 이용하였으며, 기존의 에셋을 수정하거나 가공하지 않고 모두 직접 제작하였습니다.
- Ctrl-Z는 플랫포머와 퍼즐을 합친 장르입니다. 상단의 맵에서 떨어뜨린 블록들이 하단의 맵에 영향을 받게 하였습니다.
- DropPlatform 이라는 함수를 통해서 떨어뜨리는 블록들과 맵들의 충돌을 관리합니다. 각각의 블록들의 Layer들을 바꿔주면서 충돌 여부를 바꾸어줍니다. Rigidbody2D를 적용해 자연적법칙이 블록들에 적용되도록 했습니다.
- Level 1에서는 여러가지 충돌 요소들을 통해 맵의 난이도를 올려줍니다.
- LightOn, OpenRoute등의 함수를 통해서 충돌 시 요소를 사용할 수 있게 해줍니다.
- UnityEngine의 SceneManager를 사용해서 여러 Scene들을 불러와 줍니다. 각각의 Scene 전환 스크립트들은 어떤 조건이 만족할 경우 씬을 전환해 줍니다.
- Scene 전환 시 Canvas의 검정색 Image의 알파 값을 변화해주는 방식으로 FadeIn과 FadeOut을 구성합니다.
- 플레이어와 움직일 수 있는 오브젝트들은 시간 되돌리기를 위한 TImeRewind 스크립트를 공유합니다.
- 플레이어가 장애물과 충돌하여 게임 오버되거나, 직접 R키를 누른다면 시간 되돌리기를 실행합니다
- 상단 맵에서는 플레이어가 게임 오버되거나, R키를 누른다면 상단 맵부터 시작합니다.
- 하단 맵에서 플레이어가 게임 오버된다면, 하단 맵부터 다시 시작합니다. 하단 맵에서 플레이어가 R키를 누른다면 상단 맵부터 시작합니다
- 상단 맵, 하단 맵에서의 위치를 따로 저장하기 위해 움직일 수 있는 모든 오브젝트들은 2개의 배열을 가집니다.
- 되돌리기 속도를 공간 효율성을 위해 매 프레임 위치를 저장하는 것이 아니라, 일정 주기마다 배열에 저장합니다.
- 각 Scene마다 RewindManager 객체를 만들어 시간 되돌리기 가능한 객체들을 관리합니다. RewindManager 덕분에 플레이어가 사망한다면 모든 오브젝트들이 동시에 시간 되돌리기를 수행할 수 있습니다.
- 카메라 전환 포인트와 카메라의 중점 좌표를 보관하는 배열을 활용하였습니다.
- 플레이어가 카메라 전환 포인트를 넘는다면 카메라의 중점 좌표를 다음 중점으로 이동시킵니다.
- 플레이어가 S, 아래 방향키 혹은 W, 위 방향키를 홀드 한다면 다른 사이드의 맵을 확인할 수 있습니다.
- 카메라 컨트롤이 예상대로 작동하지 않는 것을 방지하기 위해, 해당 키들을 홀드 하는 동안에는 플레이어가 움직일 수 없습니다.
- 플레이어 이동에 따른 카메라 전환과 플레이어 컨트롤에 따른 카메라 전환은 동시에 일어날 수 없게 처리하였습니다.
- 플레이어가 플래그와 충돌한다면 상단 맵에서 하단 맵으로 이동해야합니다.
- 이를 처리하기 위해 각종 플래그들과 카메라 전환에 대한 값들을 하단 맵을 위해 세팅합니다.
- 플레이어가 R키를 누른다면 하단 맵에서 상단 맵으로 이동해야 합니다.
- 이를 처리하기 위해 각종 플래그들과 카메라 전환에 대한 값을 상단 맵을 위해 세팅합니다.
- 시간 되돌리기를 위한 값들도 상단 맵에서 가능하도록 세팅합니다.