본문으로 건너뛰기

© 2026 Molayo

Unity헤드라인2026. 05. 20. 01:48

The Game Kitchen이 밝히는 The Stone of Madness 개발 중 마주한 3가지 기술적 과제

요약

The Game Kitchen이 전술 RPG 'The Stone of Madness' 개발 과정에서 겪은 렌더링, UI, 테스트 측면의 기술적 과제와 해결책을 공유합니다. Unity 엔진을 기반으로 2D 비주얼과 3D 메커니즘을 결합하기 위한 커스텀 렌더 파이프라인 구축 및 개발 효율성 최적화 사례를 다룹니다.

핵심 포인트

  • 2D 비주얼과 3D 게임플레이를 결합하기 위해 Proxy 및 Canvas 시나리오를 활용한 커스텀 렌더링 파이프라인 구축
  • Noesis를 활용한 UI 개발 간소화 및 사용자 경험(UX) 개선을 통한 워크플로 강화
  • 복잡한 게임 내 동작 테스트를 서버로 외재화하고 자동화하여 통합 과정의 안정성 확보
  • 3D 공간의 기하학적 정보를 2D 아트 스타일로 변환하기 위한 다중 렌더링 패스 구현

올해 초, The Game Kitchen은 플레이어가 다섯 명의 죄수들이 종교 재판소의 감옥에서 탈출하도록 돕는 전술 RPG(tactical RPG)인 The Stone of Madness를 출시했습니다. 이 게스트 포스트에서는 스튜디오의 개발자 세 명이 개발 과정에서 렌더링(rendering), UI, 그리고 테스트(testing) 과제를 어떻게 해결했는지 공유합니다.

저희는 The Game Kitchen이며, 최근 PC와 콘솔(consoles)로 The Stone of Madness를 출시했습니다. 저희는 최신 프로젝트 개발 중에 직면했던 가장 시급한 과제들을 기술적인 관점에서 실질적인 예시와 함께 공유하고자 합니다. 이 협업 기사에서 저희 프로그래밍 팀은 성능과 개발 효율성을 모두 최적화하기 위해 Unity에서 구현한 핵심 솔루션들을 분석합니다.

먼저, Adrián de la Torre(그래픽 프로그래머)가 게임의 독특한 시각적 스타일을 달성하기 위해 아트 파이프라인(art pipeline)을 어떻게 설계하고 렌더링했는지 설명할 것입니다. 다음으로, Alberto Martín(UI 프로그래머)은 UI 개발을 간소화하기 위해 Noesis를 어떻게 활용했는지, 그리고 사용자 피드백을 기반으로 UX(사용자 경험)를 개선하여 워크플로(workflow)를 어떻게 강화했는지 상세히 설명할 것입니다. 마지막으로, Raúl Martón(게임플레이 프로그래머)은 복잡한 게임 내 동작에 대한 테스트를 서버로 외재화(externalized)하고 자동화하여, 통합(integration)을 방해하지 않으면서도 여러 코너 케이스(corner cases)가 처리되도록 보장한 방법을 보여줄 것입니다.

광기를 멋지게 표현하기: 커스텀 렌더 파이프라인(custom render pipeline) 살펴보기

Adrián de la Torre, 그래픽 프로그래머, The Game Kitchen

The Stone of Madness는 2D 비주얼과 3D 게임플레이 메커니즘을 결합하고 있으며, 이는 독특한 기술적 과제를 제시합니다. 플레이어는 2D 세계를 보지만, 게임의 기저 시스템은 3차원 공간에서 작동하여 디자인 측면에서 독특한 이중성을 만들어냅니다.

이 과제를 해결하기 위해 저희 개발 팀은 3D 게임플레이 정보와 2D 시각적 표현 사이의 간극을 효과적으로 메우는 커스텀 렌더링 파이프라인(custom rendering pipeline)을 구축했습니다.

이 솔루션은 의도된 게임플레이의 깊이를 유지하면서 시각적 일관성을 유지하기 위해 다중 렌더링 패스(multiple rendering passes)와 특화된 기술들을 구현하며, 이를 통해 3D 요소들을 게임 특유의 2D 아트 스타일로 매끄럽게 변환할 수 있게 합니다. The Stone of Madness에는 프레임 렌더링에 기여하는 두 가지 주요 시나리오가 있습니다. 첫 번째 시나리오는 Proxy 시나리오(Proxy Scenario)라고 부르며, 최종 프레임의 라이팅(lighting)을 계산하는 기하학적 프리미티브(geometric primitives)로 구성됩니다. 두 번째 시나리오는 캔버스 시나리오(Canvas Scenario)로, Proxy 기하 구조의 모양 및 위치와 일치하는 스프라이트(sprites)로 구성됩니다. 캔버스는 3D 공간을 시뮬레이션하고 움직이는 게임 요소들과 적절한 Z-정렬(Z-sorting)을 달성하기 위해 레이어(layers)로 배치됩니다. 다음 섹션에서는 프레임 렌더링을 위한 그래픽 파이프라인(graphics pipeline)의 각 단계를 자세히 설명합니다.

  1. 시야 원뿔 (Cone of vision)
    시야 원뿔(cone of vision)이나 게임 능력이 활성화될 때마다 파이프라인의 첫 번째 단계가 시작됩니다. 우리는 NPC의 시점(PoV, Point of View)에 카메라를 배치하여 시야 범위(FoV, Field of View) 내 프록시(proxies)의 깊이(depth)를 렌더링합니다. 그런 다음, 또 다른 렌더 텍스처(render texture)에서 카메라는 플레이어의 원점으로부터의 거리 구배(gradient)를 B 채널에 출력하며, 이는 스킬 범위 효과(skill area effects)에 사용됩니다. NPC의 PoV 렌더 텍스처를 사용하여, 시야 원뿔 카메라는 장애물과 거리에 대한 정보를 담아 이전 텍스처의 R 및 G 채널 위에 원뿔을 렌더링합니다. 마지막 패스(pass)는 알파(Alpha) 채널에 음파(sound waves)를 렌더링합니다. 이것이 이 단계에서 생성되는 최종 텍스처이며, 이후 캔버스 카메라(Canvas Camera) 단계에서 장면의 스프라이트를 렌더링하는 데 사용됩니다.

  2. 캔버스 렌더 ID 카메라 (Canvas Render ID Camera)
    우리 프로젝트의 각 프록시에는 연관된 렌더 ID(Render ID, float 값)가 있습니다. 프록시와 그와 관련된 스프라이트는 동일한 렌더 ID를 공유합니다. 이 단계에서 우리는 렌더 ID float 값을 렌더 텍스처에 렌더링합니다. 이어지는 단계에서, 우리는 이 텍스처를 사용하여 프록시 시나리오에서 계산된 라이팅 정보와 캔버스 시나리오의 스프라이트를 일치시킵니다.

라이팅 (Lighting)
우리 게임의 라이팅은 다음과 같이 구성됩니다:

  • 베이크드 라이팅 (Baked lighting): 외부 조명과 같이 영구적으로 활성화된 상태로 유지되는 자연광
  • 믹스드 라이팅 (Mixed lighting): 양초와 같이 씬(Scene) 내에서 켜고 끌 수 있는 정적 조명 (Static lights)
  • 실시간 라이팅 (Real-time lighting): 씬 전체를 움직이며 켜고 끌 수 있는 조명 (우리는 이를 단 한 가지 사례, 즉 Alfredo의 오일 램프에만 구현했습니다)

RenderID 텍스처를 사용하여, 프록시 씬 (Proxy scene)의 라이팅 정보를 포함하는 렌더 텍스처 (Render texture)를 생성합니다.

  1. 캔버스 카메라 (Canvas Camera)
    모든 렌더 텍스처를 생성한 후, 카메라가 라이팅, 스킬 범위 효과 (Skill areas of effect), 시야각 (Cones of vision), 노이즈 파동 (Noise waves)에 관한 정보를 포함하여 스프라이트 (Sprites)를 렌더링하기 시작합니다.

  2. 포스트 프로세싱 (Post-processing)
    컬러 그레이딩 (Color grading), 비네팅 (Vignetting) 및 기타 효과들이 포스트 프로세싱 패스 (Post-processing pass)에서 적용됩니다.

  3. UI
    마지막으로, UI가 오버레이 (Overlay)됩니다.

HUD의 광기: UI 프로세스 가속화
Alberto Martín, UI 프로그래머, The Game Kitchen

The Stone of Madness의 최종 출시 버전에는 50개 이상의 사용자 인터페이스 (User interfaces)가 포함되어 있습니다. 이 숫자가 이렇게 큰 이유는 이 게임이 사용자에게 보여줘야 할 데이터가 매우 많기 때문입니다. 우리의 UI 작업은 매우 많은 시간이 소요되었으며, 특히 프로젝트 초기 팀 규모가 작았기 때문에, 가능한 한 짧은 시간 내에 좋은 결과를 얻을 수 있도록 프로세스를 지속적으로 최적화했습니다.

우리의 UI 작업은 프로젝트 전체에 걸쳐 진행되었으므로, UI/UX 디자이너들이 우리가 구현해야 할 모든 기능을 명확하게 이해하는 것이 중요했습니다. 게임이 좋은 사용자 경험 (User experience)을 제공하고 재미있게 플레이될 수 있도록, 우리는 프로그래밍 팀과 디자인 팀 사이에 열린 소통 창구를 유지하기 위해 주의를 기울였습니다.

모든 UI 컴포넌트 (UI components)의 최상의 버전을 만들기 위해, 우리는 기술 팀과 크리에이티브/리서치 팀 사이의 사일로 (Silos)를 제거하여 모든 구성원이 게임 개발에 적극적으로 참여할 수 있도록 해야 했습니다.

우리가 이 두 부분으로 구성된 워크플로우(Workflow)에 어떻게 접근했는지 소개합니다.

UI 디자인에서 리서치 및 크리에이티브 팀의 역할
우리의 UI/UX 디자이너들은 UI 요소가 최종 게임에서 어떻게 보일지 정의하고, 만족스러운 사용자 경험 (User Experience, UX)을 제공할 수 있도록 보장하는 책임을 집니다. 이를 염두에 두고, 디자이너들은 기술적 부하 (Technical load)를 최소화하여 각 요소를 생성하고 잠재적 사용자들을 통해 이를 검증하는 것부터 시작했습니다. 그 과정은 다음과 같았습니다:

  • 요구 사항 (Requisites): 플레이어의 니즈를 이해하고 게임의 필요 사항 및 사용자 목표 목록을 작성합니다.
  • 조사 (Investigation): 다른 게임들이 유사한 문제를 어떻게 처리했는지 살펴봅니다.
  • 와이어프레임 (Wireframes): 도식과 구조를 작업합니다 (이 단계에서는 최종 아트가 포함되지 않습니다).
  • 목업 (Mock-up): 이 단계에서는 이전에 생성된 요소들(버튼, 스크롤, 프레임 등)을 사용하여 거의 완전히 디자인된 인터페이스를 배치하며, 이를 통해 큰 노력 없이 반복 작업 (Iteration)을 할 수 있습니다.
  • 프로토타입 (Prototype): 목업을 사용하여 Figma 상에서 프로토타입을 구축하고, 게임패드 및 키보드/마우스와의 상호작용을 시뮬레이션하여 실제 환경에서 어떻게 작동할지 보여줍니다.
  • 사용자 테스트 (User test): 이전에 생성한 프로토타입을 사용하여 사용자 테스트를 시작하고, 1단계에서 식별한 니즈와 목표를 검증합니다.
  • 반복 단계 (Iteration phase): 사용자 테스트가 기대치를 충족하면 기술적인 구현 프로세스로 넘기거나, 더 많은 반복 작업을 수행하거나, 상황이 여의치 않으면 추가 테스트를 진행합니다.

기술적 UI 구현
앞서 언급했듯이, The Stone of Madness의 UI 요소 수는 엄청납니다. UI 엔진을 직접 개발하는 것은 비용이 많이 들기 때문에, 우리는 괜찮은 도구와 워크플로우를 갖추고 배우기 쉬운 프레임워크를 사용해야 했습니다. 다양한 미들웨어 (Middleware)를 평가한 끝에, 우리는 모델-뷰-뷰모델 (Model-View-ViewModel, MVVM) 패턴을 따르는 Noesis GUI를 선택했습니다.

우리가 Noesis를 선택한 이유는 이것이 WPF (Windows Presentation Framework)를 기반으로 하며, 대부분의 문서, 참고 문헌, 포럼 게시물 등을 재사용하여 대다수의 문제를 해결할 수 있는 방식으로 MVVM 모델을 따르기 때문입니다.

이 프레임워크는 처음 출시된 지 18년이 된 만큼 꽤 오랫동안 존재해 왔으며, 수많은 UI 개발자들에게 익숙합니다. 덕분에 우리 스튜디오는 프로젝트를 위한 인터페이스와 도구를 구현할 때 비교적 더 넓은 인재 풀에서 인력을 채용할 수 있는 선택권을 가집니다. Noesis의 또 다른 중요한 점은 WPF에서 사용하던 것과 동일한 도구들을 사용할 수 있다는 것입니다. XAML을 통해 우리의 UI 크리에이티브 팀은 최소한의 기술적 개입만으로 레이아웃 작업과 모든 요소의 다듬기(polishing) 작업에 참여할 수 있었습니다. MVVM 접근 방식 덕분에, 기술 UI 프로그래머들은 기능 구현에 집중할 수 있었고 필요한 경우 특정 영역에서 크리에이티브 팀에 지원을 제공할 수 있었습니다.

테스트 (또는 시스템 설계 기반의 게임을 만들 때 미치지 않는 방법)
Raul Martón, Teku Studios 게임플레이 프로그래머

'The Stone of Madness'의 게임플레이는 플레이어 기술(Player skills), NPC AI, 그리고 장면 상호작용(scene interactions)이라는 세 가지 근본적인 기둥을 기반으로 합니다. 이 세 가지 시스템은 근본적으로 서로 얽혀 있으며, 이는 플레이어가 제어해야 하는 상황의 수와 우리가 테스트해야 하는 시나리오의 수를 기하급수적으로 증가시킵니다.

프로젝트를 시작하자마자 우리는 전통적인 QA(Quality Assurance) 시스템만으로는 불충분할 것이라는 점을 깨달았습니다. 여러 요소가 특정한 방식으로 상호작용하여 통제되지 않는 상황을 만드는 시나리오가 너무나 많았습니다. 게다가 이러한 상황들은 QA 팀이 편안하게 테스트하기에는 너무 짧은 시간 범위 내에서 발생할 수도 있었습니다.

이러한 문제들을 해결하기 위해 우리는 자동 테스트(automatic tests) 세트를 구축했습니다. 특정 시스템과 관련하여 개발 팀에 발생할 수 있는 모든 가능한 시나리오/상황을 시뮬레이션된 게임 환경에서 훨씬 더 효율적으로 고려하고 자동으로 테스트할 수 있도록 하는 것이 아이디어였습니다.

예를 들어, 'The Stone of Madness'의 주요 캐릭터 중 한 명인 Amelia Exposito는 소매치기(pickpocket) 능력을 가지고 있습니다.

이 기술을 구현하는 동안, 우리는 다음 사항들을 보장하기 위해 일련의 테스트를 시작했습니다:

기술의 기본 기능이 올바른지 확인: NPC로부터 물건을 훔칠 때, 소매치기 미니게임(pickpocketing mini-game)이 열리고 게임이 종료될 때까지 일시 정지(pause)되는지 확인합니다.

덜 일반적인 상황들도 포함: 만약 다른 NPC(예: 경비병)가 당신을 지켜보고 있는 동안 NPC에게 물건을 훔치려 하거나, 해당 NPC가 달리고 있는 경우, 해당 행동은 불가능해야 합니다.

통합 테스트(Integration test) 생성
우리가 생성한 각 통합 테스트는 다음 요구 사항을 기반으로 한 설정이 필요했습니다:

  1. 이러한 특정한 상황을 만들기 위해 특별히 준비된 장면(Scene)
    소매치기 기술을 테스트하기 위해, 우리는 두 명의 경비병과 한 명의 플레이어가 있는 장면을 만들었습니다. 우리는 각 캐릭터가 상황을 정확하게 테스트하는 데 필요한 방향을 바라보도록 배치했습니다(기억하세요, 플레이어가 경비병의 시야(FoV) 안에 있다면 소매치기를 사용할 수 없습니다).

또한, 장면에는 시나리오를 테스트하는 데 필요한 최소한의 구성 요소만 포함되어야 합니다. 불필요한 요소들은 측정에 노이즈(noise)를 더할 수 있기 때문입니다. 이것이 우리의 예시 장면에는 HUD, 수동 입력 시스템(manual input system), 음향 효과 등이 없는 이유입니다.

이 단계는 게임 구조가 잘 구획화(compartmentalized)되어 있을 것을 요구하며, 이는 어느 정도 노력이 필요할 수 있지만, 일단 달성하고 나면 그만한 가치가 충분합니다! 😉

테스트 상황을 강제로 발생시킬 수 있는 테스트 코드

우리가 테스트해야 했던 많은 상황은 수동으로 생성하기 어렵고 시간이 많이 소요되며, 이를 시작하기 위해 코드 푸시 (code push)가 필요할 수 있습니다. 예를 들어, NPC가 이동 중이 아닐 때 절대 쥐덫을 밟지 않는지 확인하기 위한 테스트 시나리오를 만들고 싶다면, 명령 체계는 다음과 같을 것입니다:

  1. 씬 (scene) 실행
  2. 1초 대기
  3. NPC 아래에 쥐덫 생성
  4. 추가로 1초 대기
  5. NPC에게 아무 방향으로나 걷기 시작하도록 명령

이 프로젝트의 이 부분은 개발 과정 중의 모든 변화(게임 사양 변경 및 다양한 예기치 않은 시나리오와 같은 요인에 의존함)에 매우 민감하므로, 테스트 코드와 그 결과로 나오는 피드백이 가능한 한 명확해야 하는 것이 매우 중요합니다. 무엇이 실제로 잘못되고 있는지에 대한 명확한 정보도 제공하지 못한 채 실패하는 테스트보다 더 나쁜 것은 없습니다.

  1. 시나리오가 의도한 대로 작동하는지, 또는 테스트가 로직 (logic)의 오류를 감지했는지 알 수 있는 신뢰할 수 있는 방법

자동화된 테스트 (automated testing)에도 여전히 감독이 필요합니다. 테스트되는 대상이 구체화됨에 따라 테스트의 수가 늘어나면 모니터링이 어려워질 수 있으며, 시나리오가 통계적으로 유의미할 만큼 충분히 오랫동안 테스트되지 못하는 상황이 발생할 수도 있습니다. 이러한 문제를 해결하기 위해 우리는 커스텀 도구 (custom tools)를 제작했습니다.

예를 들어, 우리의 일부 테스트는 한 씬 내에 있는 여러 NPC 간의 결합된 상호작용을 포함했습니다. 이러한 케이스들을 적절히 모니터링하기 위해, 우리는 테스트 중에 NPC가 순환하는 다양한 AI 상태 (AI states)를 기록하는 시스템을 만들었습니다.

또한 우리는 현재 게임 상태를 가시화할 수 있는 좋은 API (API)가 필요했습니다 (예: NPC가 의식을 잃었는가? NPC가 퇴각 (routed) 상태에 진입했는가? 몇 번이나 발생했는가? 어떤 플레이어 캐릭터가 포획되었는가? 등).

  1. 이 모든 테스트를 빠르게 실행할 수 있는 시스템:

유닛 테스트 (unit tests)와 달리, 자동화된 테스트는 게임이 실시간으로 실행되는 상태에서 수행되어야 합니다.

이로 인해 이러한 테스트를 실행하는 속도가 매우 느려질 수 있습니다. 이러한 상황에서 우리는 우리 게임이 Unity의 표준 업데이트 (standard updates) 시스템을 사용하지 않는다는 점을 활용할 수 있습니다. In

AI 자동 생성 콘텐츠

본 콘텐츠는 Unity Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0