Retirement Rumble: Fabled Fogies
Vancouver Film School | 게임 디자이너 및 프로그래머 | 2024년 6월 ~ 2024년 12월 | itch.io 페이지
Retirement Rumble: Fabled Fogies는 3D 아이소메트릭 난투형 격투 게임으로, 은퇴한 하이 판타지 영웅 6명이 고인이 된 Raging Rita의 Big Room을 놓고 경쟁하는 게임입니다. Raging Rita의 삶을 기리기 위해 그녀가 가장 좋아했던 휴양지에서 격돌하세요! 세 명의 상대를 녹아웃시키고 경기장 밖으로 던져 최후의 생존자가 되어보세요.
이 프로젝트에서 게임 디자이너와 프로그래머로서 참여했습니다. 창의적인 토론이 가득했던 초기 디자인 회의부터 Pitch and Play 발표까지, 훌륭한 팀원들과 함께하며 즐거운 경험을 쌓았고, 게임 개발에 대해 많은 것을 배울 수 있었습니다.
주요 성과
래그돌


애니메이션의 첫 번째 프레임의 Bone Transform은 래그돌의 ResettingBones 메서드에서 사용되기 전에 Awake에 저장됩니다.
문제
캐릭터가 화면을 가로질러 날아다니는 모습을 보고 웃음을 터뜨린 첫 반응을 바탕으로, 래그돌은 저희 게임의 핵심 요소로 자리 잡게 되었습니다. 하지만 래그돌 상태로 날아간 캐릭터가 반드시 죽은 것이 아니라는 문제가 있었습니다. 캐릭터가 자연스럽게 다시 일어설 수 있도록 하려면 어떻게 해야 할까요?
해결책
이 문제를 해결하기 위해 KO 상태와 일어나는 상태 사이에 중간 단계를 추가했습니다. 캐릭터의 bone transform을 일어나는 애니메이션 첫 프레임의 bone 위치로 slerp하도록 설정했습니다. 표준 인간 모델과는 다른 저희 캐릭터의 독특한 비율을 고려하여 애니메이션 자체에 몇 가지 조정을 해야 했지만, 결과에 매우 만족했습니다. 따라서 캐릭터는 다시 공격할 준비를 하기 위해 원래 애니메이션 상태로 부드럽게 전환됩니다.
이 해결책은 래그돌에 관한 다음 동영상에서 영감을 받았습니다.
레벨 위험


인터페이스는 UniRX와 함께 Game Object 간 상호 작용을 위해 광범위하게 사용되었습니다. 이 예에서 몬스터는 타격을 받는 객체의 ITargettable 인터페이스를 확인하고, 대상이 플레이어인 경우 MainEventHandler 통해서 추가적인 플레이어 통계를 추적합니다.
개요
모든 레벨에는 핵심 게임플레이 요소 중 하나인 Controlled Chaos를 강조하기 위한 몬스터가 포함되어 있습니다. 게임의 각 액션은 간단하고 따라하기 쉬운 의미에서 Controlled이지만, 동시에 너무 많은 액션이 진행되어 모든 것을 추적하기 어려운 Chaos를 만들어냅니다.
이러한 레벨 몬스터를 구현하는 과정은 Unity에서 State Machine, Animation Events, Physics System을 다루는 지식을 넓힐 수 있는 기회였습니다. 또한 각 몬스터에 대한 초기 아이디어가 실제 빌드에서 상당히 다르게 구현되는 과정을 통해 디자인 역량도 크게 향상되었습니다.
디자인 변경
가장 많은 변화를 겪은 몬스터는 두 번째 레벨의 용이었습니다. 초기 디자인에서는 용이 돌풍을 뿜어 플레이어를 경기장 밖으로 밀어내는 역할을 했습니다. 노인(Fogey)이라는 테마를 유지하려고 최대한 노력했지만, 플레이테스트를 진행하면서 이 디자인의 약점이 드러났습니다. 문제는 두 가지였습니다:
-
다른 레벨의 몬스터는 플레이어를 즉시 KO시킬 수 있었던 반면, 용의 돌풍은 플레이어를 맵 밖으로 밀어내는 간접적인 방식이었기 때문에 레벨의 전략적인 플레이를 이해하기가 힘들었습니다.
-
용은 다른 몬스터에 비해 영향력이 약했습니다. 다른 레벨에서는 몬스터를 통해 포인트를 획득할 기회가 많았지만, 용을 통해서는 직접적인 포인트 획득이 불가능했습니다.
제가 생각해낸 해결책은 용이 플레이어를 직접 KO시킬 수 있는 뼈를 뱉게 만드는 것이었습니다. 이 해결책은은 위의 문제를 해결하면서도 게임의 테마와 톤을 유지할 수 있었습니다. 플레이테스트 결과, 이 아이디어는 효과적임이 증명되었습니다. 플레이어는 뼈의 역할을 즉시 이해했고, 다른 레벨과 유사하게 몬스터 중심의 전략적인 플레이를 시작했습니다.
Reactive Event 시스템

UniRx는 위의 대포 경고 표시기와 같이 game object 간 communication에 사용되었으며 아래 code snippet은 어떻게 구현되었는지 보여줍니다.


플레이어가 대포를 장전했을때 MainEventHandler에 위치한 custom static method통해서 custom struct를 EventStream에 추가했습니다.
위의 대포 경고 표시기는 Event Hub를 통과하는 해당되는 이벤트에 대해서만 수신하면 됩니다.

UniRX는 또한 각 경기가 끝날 때마다 Player Card에 사용된 다양한 유형의 통계 추적에도 광범위하게 사용되었습니다.
왜 RX?
처음에는 Actions를 사용하여 메서드에 직접 Subscribe/Unsubscribe하며 Game Object 간 긴밀한 결합(coupling)을 형성했습니다. 초기에는 큰 문제가 없었지만, 번거로운 iteration cycle과 코드 변경 시 정리 작업이 필요하다는 징후가 점차 나타나기 시작했습니다. 다행히도 Reactive Extensions for Unity(UniRx)를 활용하여 리액티브 프로그래밍 기반의 Event System을 도입함으로써 이러한 문제를 해결할 수 있었습니다.
Event System의 핵심은 Centralized Event Hub에서 특정 이벤트를 수신하는 메서드가 이벤트 스트림에 추가된 데이터를 구독(Subscribe)하는 방식입니다.
결과
이 접근 방식 덕분에 Game Object 간 특정 상호작용을 구현할 때마다 발생하던 엄청난 오버헤드를 절약할 수 있었습니다. 또한, 의도치 않은 iteration cycle을 피할 수 있었고, Game Object가 삭제되거나 변경될 때 null reference에 대해 걱정할 필요도 없어졌습니다.
더불어, 데이터 스트림의 커스터마이징 가능한 특성 덕분에 Game Object가 이벤트에 반응하는 방식을 훨씬 더 효과적으로 제어할 수 있었습니다.
파괴 가능 소품


OnEnable은 여기서 Start 대신 Object Pooling 시스템에 사용되어 성능을 높입니다. PrimeTween Sequence는 위치, 회전, 흔들림을 포함하는 작은 애니메이션에 광범위하게 사용되었습니다.

localPosition은 0으로 재설정되어 조각이 적절한 위치로 돌아가 다음에 Game Object가 깨질 때 호출됩니다. 그렇지 않으면 이동된 조각은 파괴된 상태로 Pool로 돌아갑니다. ReturnToPool은 이 PooledObject 클래스에서 inherit해서 받은 메서드입니다.
개요
파괴 가능한 소품은 플레이테스터가 장식용 플레이스홀더 소품을 상호작용하려고 시도한 결과로 탄생했습니다. 플레이어가 "제대로" 플레이하도록 유도하기 위해 이 소품을 제거하는 대신, 피드백을 바탕으로 다양한 파괴 가능한 Game Object 추가하기로 결정했습니다.
아이디어와 구현은 제가 주도했지만, 이 과정은 긴밀한 협업을 통해 이루어졌습니다. Environment 및 VFX 아티스트와 협력하여 비주얼이 게임의 스타일과 일치하도록 조율했으며, 레벨 디자이너와 함께 플레이어 피드백을 반영해 기능을 개선했습니다.