Unity 검색

생태계를 만드는 시스템: 새로운 게임 디자인

2021년 12월 7일 게임 | 10 분 소요
Hero
Hero

게임 디자이너는 간단한 스크립트만으로도 플레이어를 즐겁게 하는 흥미롭고 예상치 못한 게임플레이가 담긴 게임 시스템을 제작할 수 있습니다. 유니티는 게임 디자이너 Christo Nobbs와 함께 Unity의 몇 가지 주요 기능을 활용해 새로운 게임플레이를 디자인한 방법에 대해 이야기를 나누어 보았습니다. 

여러 개인 크리에이터나 게임 스튜디오와 수년에 걸쳐 나눈 대화를 살펴보면, 게임 디자이너가 Unity를 사용해 게임플레이와 메커니즘을 디자인했을 때 다른 팀에게 게임에 대한 비전을 명확하고 더 자세하게 보여줄 수 있다는 사실을 알 수 있습니다.

유니티는 Unity 엔진을 이용하여 게임플레이를 프로토타이핑하고, 제작 및 테스트하는 방법을 알고 싶은 게임 디자이너를 위해 새로운 전자책 Unity 게임 디자이너 플레이북을 제작했습니다. 이 가이드는 Unity 기술을 배우기 시작하는 초보 게임 디자이너와 숙련된 게임 디자이너 모두에게 도움이 됩니다.

전자책 제작에는 시스템 게임 디자인과 Unity(C#)를 전문으로 다루는 선임 테크니컬 게임 디자이너인 Christo Nobbs가 도움을 주었습니다. 이 블로그 포스팅은 게임 디자이너를 위한 시리즈의 첫 게시글로, 전자책에서 소개한 시스템 디자인을 위한 몇 가지 팁과 예제를 조금 더 자세히 소개합니다.

Test project
화재 전파 시스템과 화재로 인한 혼란을 보여 주는 테스트 프로젝트의 이미지

게임 디자인에서는 기능이 명확하고 데이터를 보관하는 모듈식 시스템이 유용합니다. 그래야 다른 시스템과 상호 작용할 수 있을 뿐만 아니라 다른 게임 오브젝트에서도 다양한 방식으로 상호 작용할 수 있습니다. 체계적인 게임 시스템을 완전한 아키텍처가 아닌 게임 내에서 반복적으로 실행할 수 있는 기능의 일부로 보는 것이 도움이 될 수 있습니다.

그러한 시스템을 결합하면 플레이어의 행동에 반응하고 숨겨진 하드 코딩된 값과 달리 '디자인 레버(design lever)'를 사용하여 균형을 이루는 고유한 생태계를 만들 수 있습니다. 디자인 레버를 배치해 데이터를 조작하면 체계적인 게임플레이를 만들 수 있습니다.  

대부분의 게임은 최소 하나 이상의 시스템이 있으며, 게임플레이를 통해 값을 조정할 수 있는 하나의 메카닉이거나 다수의 시스템으로 이루어져 있습니다. Age of Empires 와 같은 전략 게임은 플레이어가 성장하고 적을 물리치기 위해 자원을 활용하고 조작하는 방법을 학습해야 하며, 이 경우에는 게임플레이가 복잡한 생태계에 좌우됩니다.

궁극적으로 플레이어가 게임을 어떻게 진행할지는 게임 디자이너에게 달려 있습니다. 게임플레이가 안내된 대로 선형적인 경로를 따를 것인지, 유기적이고 새로운 결과를 만들어 낼 수 있는 하나 또는 여러 시스템을 따를 것인지는 게임 디자이너가 결정할 수 있습니다.

흥미로운 게임플레이를 만드는 모듈식 시스템

흥미로운 게임플레이 루프를 만들려면 소규모 시스템을 디자인할 때 시스템의 모듈성과 시스템 자체, 그리고 다른 시스템과의 인터페이스 기능을 우선적으로 고려해야 합니다. 한 시스템이 다른 오브젝트를 통해 자체 충돌하거나 두 개의 간단한 시스템을 사용하여 플레이할 수 있는 상황을 만들었을 때 발생할 수 있는 연쇄 반응에 대해 생각해야 합니다. 게임에서 바람직한 플레이를 하기 위한 시스템의 작동 방법을 합리적으로 학습하게 하려면 항상 플레이어 입장에서 기능이 명확한 시스템을 만들어야 합니다.

Oxygen Not Included
Klei에서 제작한 Oxygen Not Included

게임 Oxygen Not Included의 연쇄 반응을 예로 들면, 이 게임의 주요 루프 목표는 계속 생존하기 위해 공생하는 유토피아 상태를 만들도록 여러 시스템의 균형을 이루는 것입니다. 또 다른 예로 Larian Studios에서 제작한 Divinity Original Sin 2 들 수 있습니다. 이 게임에서는 플레이어가 폭발하는 몹을 물에 젖게 만들면 몹이 플레이어를 공격할 수 없어 전투를 더 쉽게 이끌 수 있습니다. 플레이어는 땅에 불을 붙여 몹이 플레이어를 공격하지 못하도록 자신을 보호할 수도 있습니다. 

모듈식 시스템은 한 시스템의 일부를 사용하여 다른 시스템을 만들 수 있기 때문에 게임을 더 풍부하게 만들 수 있습니다. Christo는 게임의 거의 모든 부분에 Unity의 Animation Curves 기능을 사용합니다. Christo는 "Animation Curves의 데이터 처리는 항상 거의 똑같으며, 균형을 이루는 데 있어 하나의 값을 사용하는 것보다 더 많은 부분을 제어할 수 있다"고 말합니다. 그리고 "메카닉에 이징(easing) 효과를 추가하거나 시스템 제한을 오버라이드하여 세부 정보를 미세하게 조정할 수도 있다"고 덧붙입니다.

또한 모듈 단위 접근 방식으로 디자인하면 프로그래머에게 최대한 정확하게 시스템을 설명할 수 있으므로, 게임플레이 시스템을 더 효율적으로 편집하고 디버그할 수 있으며 게임 전반적으로 다양한 설정에 시스템을 재사용할 수 있습니다. 

디자인 레버

디자인 레버는 값을 조정해 결과를 조작하는 데 유용합니다. 예를 들어 게임플레이 난이도를 높이거나 낮추어 플레이어에게 보상을 주고, 원하는 수준의 복잡도를 제공할 수 있습니다. 또한 원하는 결과를 얻을 때까지 반복적으로 게임을 플레이해 값을 테스트하고 조정할 수 있습니다.

디자인 레버는 게임 개발 중 컨셉 및 프로토타이핑 단계부터 후반 작업 단계까지 활용할 수 있습니다. Christo는 순서도에 아이디어를 매핑할 때 디자인 레버를 활용한다고 말합니다. 나중에 코드 리팩터링에 크게 의존하지 않고도 시스템을 미세 조정하고 게임플레이의 가능성을 알아보려면 프로젝트 초기부터 시스템에 필요한 스위치와 레버를 고려하는 것이 좋습니다.

다음 이미지는 간단한 게임플레이를 보여 주는 그래프로 게임을 시작하면 적이 제자리에 있고 플레이어는 준비된 상태로 입장합니다. 기본적으로 플레이어는 적을 제거해야 하지만, 디자인 레버를 조작하면 게임플레이를 전환하여 초점을 바꿀 수 있습니다. 한 설정에서는 게임플레이가 제한 시간 내에 많은 적을 빠르게 제거하여 높은 점수를 얻는 데 초점을 맞추고 있지만, 다른 설정에서는 더 짧은 시간 내에 정해진 수의 적을 제거하고 남은 시간 동안 플레이어가 적이 떨어뜨린 전리품을 주울 수 있게 하는 데 초점을 맞추고 있습니다.

Gameplay design
간단한 게임플레이 디자인

이 시스템을 사용하면 쏟아지는 총알 세례 속에 좋은 아이템과 고유한 속성을 지닌 탄약을 다양하게 드랍할 수 있도록 만들 수 있습니다. 리스폰 시간 제한 등 더 많은 디자인 레버를 추가해 시스템을 확장할 수도 있습니다.

Escape from Tarkov의 무기 제작 시스템

Battlestate Games에서 제작한 Escape from Tarkov는 Unity를 이용한 체계적인 게임 디자인의 또 다른 좋은 예입니다. 이 게임에서는 아래 이미지에서 볼 수 있듯이 자체 데이터 세트로 무기를 제작할 수 있는 제작 시스템이 있습니다. 이 데이터 세트는 플레이어의 체력에 영향을 주는 것과 같이 총기의 특성과 총기를 사용한 전반적인 게임플레이에 영향을 줍니다. 플레이어의 팔다리가 부러지거나 플레이어가 질병에 걸리면 총을 사용하기가 더 어려워지는 반면, 건강한 플레이어는 무기를 더 잘 제어할 수 있습니다.

Weapon from Escape from Tarkov
Escape from Tarkov의 무기 제작 시스템

하나의 시스템인 무기를 다른 시스템인 체력과 연결하면, 플레이어는 캐릭터의 목숨뿐만 아니라 무기 성능을 보다 중요하게 여기게 됩니다. 아무도 먼지 덮개가 없거나 개머리판이 흔들리는 AK를 원하지 않을 겁니다. 목표를 제대로 쏠 수 없기 때문입니다. 이 상태라면 해당 무기가 나쁜 선택이라는 점을 분명하게 보여 줄 수 있습니다. 

속성이 다른 다양한 탄약 유형뿐만 아니라 다양한 방어구도 있습니다. 상대방이 사용하는 탄약과 방어구 유형에 따라 어떤 부분을 명중해야 가장 큰 피해를 입힐 수 있는지 정해지며, 메타 게임플레이가 만들어집니다. 각각의 시각적 신호가 있는 여러 시스템이 균형을 이룰 때 디자이너가 원하는 게임플레이의 '본질'을 끌어 낼 수 있습니다.

Escape from Tarkov
현실성을 구현하도록 디자인된 Escape from Tarkov 시스템

ScriptableObjects를 사용한 디자인 레버

Unity에서 디자인 레버를 설정하는 한 가지 방법은 ScriptableObjects를 사용하는 것입니다. ScriptableObjects는 데이터의 컨테이너로 사용할 수 있으며, 에셋으로 저장되고 씬의 다른 오브젝트에 대한 종속 관계를 만들지 않으면서 스크립트에서 참조할 수 있습니다.  

프리셋처럼 값이 다른 여러 ScriptableObject 에셋을 만들어서 이를 공유하고 교체하여 게임플레이의 전체 섹션을 바꿀 수 있습니다. ScriptableObjects는 변경 사항이 플레이 모드에서도 저장되므로 플레이 모드를 종료하고 나서 메모를 참고해 변경된 부분을 직접 구현하지 않아도 됩니다. 

예를 들어 캐릭터를 프로토타이핑할 때 ScriptableObject 에셋을 다른 값을 가진 에셋으로 교체하여 캐릭터의 분위기를 바꿀 수 있습니다. 버프 및 디버프를 프로토타이핑하거나 캐릭터 선택을 프로파일에 연결할 때도 ScriptableObject를 고려해볼 수 있습니다.

슈팅 게임을 만들면서 반동, 발사 속도, 정확도, 발사 모드, 오디오 설정, VFX 설정 등의 액션에 대해 임의의 값을 사용하는 총기 시스템을 구현했다고 가정하겠습니다. 새로운 총기 프로파일을 원하는 만큼 생성하고 플레이 모드에서 설정을 조정하면 변경한 사항을 한 번에 저장할 수 있습니다. 또한 프리셋 ScriptableObjects를 팀원과 공유하여 피드백을 주고받아 게임플레이에 적합한 설정을 찾는 데 유용하게 활용할 수 있습니다. 

디자인 레버는 코드에서 단일 변수를 대신하여 public 속성으로 사용될 수 있으며, Unity의 RangeAttribute를 사용하여 범위를 제한할 수 있습니다. RangeAttribute는 스크립트의 플로트나 정수를 특정 범위로 제한하고 인스펙터에서 슬라이더로 표시될 수 있게 합니다. RangeAttribute의 목적은 플레이 모드뿐만 아니라 실시간으로 레버를 조작하는 것이기 때문에 편집 모드에서 실행하거나 툴을 테스트할 때도 사용할 수 있습니다.

Panels
1) 범위, 툴팁, 헤더 속성. 디자인 필요에 맞게 인스펙터를 커스터마이즈할 수 있습니다. 2) 에셋 스토어에서 다운로드한 Odin으로 만든 커스텀 인스펙터 3) 다른 데이터 세트나 프로파일을 생성하는 데 사용할 수 있는 ScriptableObjects에 저장된 데이터, 이 경우에서는 다양한 특수 공격을 나타냄

여러 장르 중에서도 생존 게임에서 플레이어는 논리적이고 합리적인 결과로 이어지는 다양한 선택 사항을 확인하고, 각 과제에 대한 해결책을 찾는 플레이를 기대합니다. 자연스러운 문제와 해결책을 제시하려면 시스템을 어떻게 디자인해야 할까요? 

Klei 스튜디오에서 제작한 Don't Starve처럼 플레이어가 생존을 위해 한 지역에 머물러야 하는 예를 살펴보겠습니다. 플레이어는 적의 공격을 막기 위해 불 근처에 머무를 수 있습니다. 불을 사용하여 음식을 요리하거나 플레이어의 체온을 따뜻하게 유지할 수도 있습니다. 그러나 플레이어나 음식 또는 가연성 물체가 불에 너무 가까우면 타버릴 수 있습니다. 

이와 같은 연쇄 반응을 만들려면 어떤 종류의 시스템이 필요할까요? 플레이어가 서 있을 수 있는 볼륨(영역)을 만들어 시간에 따라 플레이어에게 열을 가하게 하거나 선형의 화재 전파 시스템으로 만들 수 있습니다. 하지만 더 시스템 중심적인 시각으로 접근할 수도 있습니다. 개별적인 화재 전파 시스템이 서로 충돌하고 게임 월드에 있는 다른 시스템과 충돌하는 연쇄 반응의 결과가 펼쳐진 상황에서 플레이어가 반응하도록 만들 수 있습니다.

Capsule Colliders
Capsule Colliders는 화재 전파 시스템 컴포넌트가 연결되어 연쇄 반응을 일으킬 때 하나의 게임 오브젝트에서 다른 게임 오브젝트로 열이 적용되는 영역을 나타냅니다. 게임 오브젝트에 불이 붙으면 영역이 빨갛게 변해 열이 가해지고 있음을 나타냅니다. 열이 가해지고 있는 게임 오브젝트는 노란색으로 변하여 열을 받고 있음을 나타내다가, 불이 붙으면 빨갛게 변합니다.

시간이 지남에 따라 연못 주변에 정의된 영역에서 나무가 성장하는 시스템을 만들 수 있습니다. 나무는 싹을 틔우고 제한된 공간에 이를 때까지 자랍니다. 나무가 다 자라면 나무를 베어서 목재로 만들 수 있으며, 목재는 물론 가연성 물체입니다.  

플레이어는 목재를 사용하여 멋진 나무 의자 등의 아이템을 만들거나 연못 옆에 작은 모닥불을 만들어 수영한 다음 옷을 말리고 몸을 따뜻하게 할 수 있습니다. 그렇다면 만약 플레이어에게 모닥불에 불을 붙일 수 있는 능력을 주면 어떤 일이 일어날까요?

나무의 가연성 시스템은 복잡하지는 않지만, 어떤 물체에 불이 붙으면 반경 내에 열을 방출하고 방출된 열 값이 한계를 넘으면 근처에 있는 목재 아이템이나 나무가 불에 붙는 단순 전파가 일어납니다. 따라서 플레이어는 모닥불에 불을 붙이려다 멋진 나무 의자에도 불이 붙게 됩니다. 이제 플레이어는 의자에 붙은 불을 끄기 위해 의자를 집어 물에 던져야 하지만, 그동안 모닥불에 붙은 불이 가장 가까운 나무에 옮겨붙으면서 산불을 꺼야 하는 상황에 이르게 됩니다. 

이 예시처럼 제한된 소규모 시스템으로도 플레이어에게 미리 계획되지 않은 흥미로운 경험을 선사할 수 있습니다. 또한 현실과 너무 비슷해서 예기치 않은 결과가 잘 일어나지 않는 디자인보다는, 플레이어에게 원하는 결과가 발생하도록 만드는 데 초점을 맞추는 것이 중요합니다. 

Unity를 사용한 이 예시에서는 불을 붙이고 싶은 모든 오브젝트의 ScriptableObject 속에 디자인 레버를 저장해 새로운 가능성을 생성할 수 있습니다. 죽은 나무가 이미 물가에서 에 타고 있고, 나무가 물 쪽으로 기울어져 있는 상황에서 플레이어가 몸을 따뜻하게 해야 하는 월드의 나무를 예로 들어 보겠습니다.

이 예에서 나무에는 다양한 값을 지닌 ScriptableObject가 있습니다.

Panel
Code

값을 더 자세히 살펴보겠습니다. 

  • 기본 온도: 전역 상태에서 상속할 값이 없는 경우 플레이스홀더 값. 월드 전반에서 온도가 높거나 낮은 경우, 모든 나무가 화재 전파 시스템을 사용한다고 가정할 때 높은 온도는 산불을 일으킬 수 있으므로 전체 시스템에 영향을 줄 수 있습니다.
  • 현재 온도: 아이템이 가열되거나 냉각될 때의 온도. 현재 온도 값이 저항 값보다 높은 경우 아이템의 연소 여부를 결정합니다.
  • 연소 온도: 아이템에 불이 붙기 위해 도달해야 하는 온도
  • 가열 속도: 다른 열원의 반경 안에 있을 때 아이템이 가열되는 속도 
  • 냉각 속도: 아이템이 가열되지 않은 온도로 돌아오는 속도. 디자인 레버 이름만으로 특성이 설명되는 경우 리텐션이나 열 품질이라고 할 수도 있습니다.
  • 연소 속도: 시간에 따라 아이템이 연소되는 속도
  • 연료: 아이템이 연소될 때 아이템이 지닌 연료의 양
  • 열 강도: 반경 내 열의 강도
  • 열 반경: 열의 도달 범위 또는 확장 범위

게임플레이 코드를 일부 사용하면 한 오브젝트 옆에 불이 붙는 다른 오브젝트를 둘 수 있습니다. 프로토타입의 프로파일을 저장하고 한계점을 찾을 때까지 다양하게 설정을 바꿔본 후 원하는 값을 속성으로 고정할 수 있습니다.

Prototyped with assets from the Asset Store
에셋 스토어의 에셋으로 프로토타이핑한 씬

물이 불을 막도록 디자인하지는 않았지만, 물 위에 가연성 물체가 없고 불이 물의 반대편까지 닿지 않으면 새로운 시스템을 추가하지 않는 한 불이 번지지 않습니다. 

화재 전파 시스템의 예를 보면 연료, 연소 속도, 열 강도를 사용해 같은 결과를 만드는 다양한 방법이 있다는 것을 알 수 있습니다. 또한, 예를 들어 연료를 '체력'으로 바꾸면 원래의 기능을 유지하면서 나무가 쓰러지는 순간을 제어할 수 있는 범위를 추가하는 등 새로운 결과를 만들어 낼 수도 있습니다. 나무의 체력이 낮아지면 나무가 쓰러질 확률이 높아집니다. 불에 타고 있는 나무의 체력이 낮아지면 나무가 쓰러지고, 가연성 오브젝트가 있는 영역에 플레이어가 불타는 나무를 그대로 두면 엄청난 재앙이 일어날 수 있습니다. 

환경에 더 많은 시스템을 추가하면 시스템이 서로 반응하는 생태계를 만들 수 있습니다. 플레이어가 나무를 수확하거나, 나무를 사용하여 건축하고 아이템을 제작할 수 있는 경우 모든 아이템이 화재 전파 시스템을 상속하게 된다면 언제든지 문제가 발생할 수 있습니다. 

Panel

연소 한곗값을 줄이고 가열 속도를 높이면 오브젝트가 더 빠르게 연소되는 휘발성 높은 화재 전파 설정을 만들 수 있습니다. 화재가 더 빠르고 제어할 수 없을 정도로 퍼져나가게 하려면 반경을 늘리면 됩니다. 가열 속도는 세분화를 위해 0부터 50까지로 제한되어 있습니다. 열 강도를 사용해 가열 속도 값을 배로 만들 수 있지만, 합리적인 값을 사용하는 것이 좋습니다. 열 강도를 4로 설정하면 가열 속도를 0에서 200까지 늘릴 수 있지만, 이 값은 너무 크고 순식간에 산불이 일어날 수 있습니다. 플레이어가 화재를 진압하기 위해 반응할 시간조차 없기 때문에 좋은 게임플레이 경험을 만들 수 없습니다.

Panel

연소 한곗값을 300으로 올리면 더 균형 잡힌 화재 전파 시스템을 만들 수 있습니다. 플레이어는 화재가 발생하기 전에 다른 작업을 할 수 있으며, 화재가 발생했을 때 빠르게 움직이면 화재에 대응하고 진압할 수 있습니다. 특히 나무를 베거나 장벽을 건설하는 등 화재 전파 시스템처럼 똑같이 체계적이고 간단한 물 시스템을 활용할 수 있다면 플레이어는 얼마든지 화재에 대응할 수 있습니다.

불의 열 반경 내에 있는 오브젝트에 저항 값을 사용하여 화재 전파 시스템을 더욱 확장할 수 있습니다. 저항 값을 추가하면 다양한 온도의 화재를 일으키거나 구조물에 내화 코팅을 사용할 수 있는 업그레이드를 추가할 수 있습니다. 너무 다양한 기능이 추가되지만, 체계적인 방식으로 게임플레이 디자인을 고려하여 플레이어가 화재 시스템과 상호 작용하면서 추운 숲 환경에서 생존하고 잘 살아 나올 가능성을 높일 수 있는 예시입니다.

A very memorable moment Don’t Starve from Klei, when a forest fire breaks out
Klei의 Don't Starve에서 산불이 났던 혼란스러운 순간

화재 전파 시스템의 예는 선형적 메카닉 아이디어를 흥미로운 경험으로 변환하여 플레이어가 게임 시스템을 배우고 이해하며 문제를 해결하도록 하는 방법을 보여 줍니다. 게임 시스템이 현실을 따라할 필요가 없다면 복잡도와 추상화를 추가로 고려할 필요가 없습니다. 

이번 포스팅에서는 간단한 예를 들어 상호 작용할 수 있는 작고 간단한 모듈식 시스템을 디자인하는 방법과 더 큰 게임플레이 생태계에서 디자인 레버로 균형을 맞추고 팀원들의 의견을 받아 미세 조정하고 반복 작업하는 과정을 알아보았습니다. 이러한 요소는 플레이어에게 예상하지 못한 재미와 즐거움, 긴장감을 선사하여 진정으로 독특한 경험을 제공하는 게임을 제작할 수 있게 됩니다. 

유니티에서 새로 선보인 무료 전자책에서 많은 팁과 영감을 얻어 더 풍부한 게임플레이를 디자인해 보세요.  

2021년 12월 7일 게임 | 10 분 소요