55개 이상의 게임을 출시하며 배운, Day One에 알았으면 좋았을 10가지 Unity 교훈
요약
55개 이상의 게임을 출시한 경험을 바탕으로, 실제 배포 과정에서 얻은 10가지 핵심 Unity 개발 교훈을 공유합니다. 이 글은 아키텍처 설계보다 재미있는 프로토타이핑의 중요성부터 메모리 최적화 및 멀티플레이어 시스템 구축 시 고려해야 할 '소유권' 문제까지 실질적인 개발 가이드라인을 제시합니다.
핵심 포인트
- 아름다운 아키텍처보다 플레이 가능한 프로토타입을 먼저 만드세요.
- 게임의 수치 데이터는 코드 대신 ScriptableObjects를 사용하세요.
- 메모리 할당(allocating)을 최소화하고 모든 객체를 풀링해야 합니다.
- 개발용 머신이 아닌, 실제 저사양 기기에서 반드시 프로파일링 하세요.
- 멀티플레이어 시스템은 초기 설계 단계부터 '소유권' 문제를 명확히 정의해야 합니다.
5년 전만 해도 저는 좋은 Unity 개발자라는 것이 API를 많이 아는 것을 의미한다고 생각했습니다.
그러다 제가 실제로 제품을 출시하기 시작했습니다. 모바일 퍼즐 게임, 16인용 소셜 게임, 55만 달러 규모의 전략 게임, VR 트레이닝 시뮬레이터, 그리고 2주 만에 제작된 핀테크 이벤트 게임까지 — iOS, Android, PC, WebGL, Meta Quest 등에서 55개 이상의 타이틀을 출시했습니다.
실제 배포 경험은 어떤 튜토리얼도 가르쳐주지 못하는 것들이었습니다. 여기 제가 가장 많은 시간, 버그, 그리고 정신적 안정을 지켜준 10가지 교훈이 있습니다.
1. 아키텍처를 설계하기 전에 재미있는 프로토타입을 먼저 만드세요
게임 개발에서 가장 비싼 실수는 재미없는 게임에 아름다운 아키텍처를 구축하는 것입니다.
이제 저는 사람들에게 가능한 한 빨리 플레이 가능한 버전을 보여줄 수 있습니다. 회색 상자(grey boxes), 플레이스홀더 UI, 하드코딩된 값들로 말이죠. 만약 핵심 루프가 큐브로는 재미없다면, 아트워크를 입혀도 재미있지 않을 것입니다.
제가 팀을 위해 신속 프로토타이핑 파이프라인을 구축했을 때, 첫 플레이 가능한 빌드를 만드는 시간이 약 30% 감소했습니다. 비결은 도구가 아니라, 일부러 버릴 코드(throwaway code)를 작성할 수 있는 허가였습니다.
규칙: 프로토타입 코드는 지저분해도 괜찮습니다. 하지만 실제 운영 코드(Production code)는 안 됩니다. 이 둘을 절대 혼동하지 마세요.
2. 숫자는 코드에 넣지 말고 ScriptableObjects에 넣으세요
만약 디자이너가 적의 속도를 변경해 달라고 요청해야 한다면, 당신의 아키텍처가 잘못된 것입니다.
[CreateAssetMenu(menuName = "Game/Enemy Config"]
public class EnemyConfig : ScriptableObject
{
...
이제 디자이너들은 Inspector에서 게임을 조정할 수 있고, 당신은 새로운 코드 없이 변형체(FastEnemy, TankEnemy)를 만들며, 밸런싱 작업이 더 이상 할 일 목록의 티켓으로 남아있지 않습니다.
3. Hot Path에서는 메모리 할당(allocating)을 멈추세요 — 생성되는 모든 것을 풀링하세요
가비지 컬렉션(Garbage collection) 스파이크는 모바일에서
4. 지원하는 최악의 기기에서 프로파일링하세요. 개발용 머신이 아닙니다.
개발자님의 노트북은 당신을 속입니다. 에디터(Editor)에서는 120 FPS로 돌아가는 게임도, 플레이어 대다수가 소유한 3년 된 저가형 안드로이드 휴대폰에서는 25 FPS로 작동할 수 있습니다.
모바일 출시 전 제가 확인하는 체크리스트:
- 실제 저사양 기기에서 개발 빌드를 프로파일링하세요. 에디터만 사용하지 마세요.
- 프로파일러(Profiler)의 GC Alloc 열을 확인하세요. 게임 플레이 중에는 0에 가까워야 합니다.
- 드로우 콜(draw calls)과 오버드로(overdraw)를 확인하세요. 특히 투명한 UI나 파티클에서 주의해야 합니다.
- 30분 세션을 테스트하세요. 메모리 누수(memory leaks)는 2분 만에 나타나지 않습니다.
5. 멀티플레이어 권한을 초기에 결정하세요.
멀티플레이어는 나중에 '추가하는' 기능이 아닙니다. 모든 시스템의 작성 방식 자체를 바꿉니다.
근접 음성 채팅(proximity voice chat)이 있는 16인치 소셜 게임에서, 가장 어려운 버그들은 네트워킹 라이브러리에서 온 것이 아니라 불분명한 소유권에서 왔습니다. 이 오브젝트는 누가 움직이나요? 이 퀘스트가 완료되었다고 누가 결정하나요? 두 플레이어가 같은 아이템을 집으려고 할 때 누가 승리하나요?
네트코드(netcode)를 작성하기 전에, 모든 상태(state)에 대해 다음 내용을 적어보세요:
| 상태 | 소유자 | 동기화 방식 |
|---|---|---|
| 플레이어 위치 | 소유 클라이언트 | 연속 동기화 |
| ... | ||
| 그 표 하나가 어떤 라이브러리 기능보다도 많은 디버깅 시간을 절약해 주었습니다. |
6. 백엔드를 일찍 구축하세요. 아주 작은 것이라도 괜찮습니다.
첫 주부터 Firebase나 PlayFab을 사용하면 세 가지 초능력을 얻게 됩니다:
- 원격 설정(Remote config) — 새로운 빌드를 배포하지 않고 난이도, 가격 및 보상을 조정할 수 있습니다.
- 분석(Analytics) — 추측하는 대신 플레이어가 실제로 이탈하는 지점을 찾을 수 있습니다.
- 리더보드 및 클라우드 저장(Leaderboards and cloud saves) — 플레이어들이 기대하는 기능이며, 추가하기 거의 무료에 가깝습니다.
백엔드를 나중에 추가한다는 것은 모든 저장 데이터, 모든 보상, 모든 숫자를 개조해야 한다는 의미입니다. 시작할 때 추가한다는 것은 새벽 2시에 설정 변경만으로 잘못된 레벨을 수정할 수 있다는 뜻입니다. 스토어 검토를 기다릴 필요 없이 말이죠.
7. 마감 기한이 있다면 범위를 줄이고, 품질은 절대 포기하지 마세요.
싱가포르의 핀테크 회사 라이브 이벤트를 위해 이벤트 게임을 제작한 적이 있습니다. 기획은 2주 이내에 완료해야 했고, 리더보드, 비디오 설명자 및 퀴즈 기능이 포함되어 있었습니다.
우리는 가차 없이 기능을 줄였기 때문에 제시간에 출시할 수 있었습니다. 세 가지 게임 모드 대신 하나만 사용하고, 하나의 아트 스타일을 적용했으며, 플랫폼도 하나(WebGL — 현장에서 설치할 필요 없음)로 제한했습니다. 줄이지 않은 것은 입력 반응성, 로드 시간, 그리고 부하 상태에서 작동하는 리더보드였습니다.
플레이어들은 빠진 기능은 용서합니다. 하지만 제대로 작동하지 않는 게임은 용서하지 않습니다.
8. AI API 키를 게임 클라이언트에 포함시키지 마세요
AI 기능은 이제 어디에나 있습니다 — 채팅 비서, 생성형 콘텐츠, 스마트 NPC 등입니다. 제가 가장 흔하게 보는 실수는 OpenAI 또는 Gemini 키를 빌드 안에 넣는 것입니다. 누구나 몇 분 만에 추출할 수 있습니다.
게임과 AI 제공자 사이에 작은 서버 함수를 두고, 대신 그것을 호출하세요:
using System.Collections;
using System.Text;
using UnityEngine;
...
서버가 키를 비밀로 유지하고, 각 플레이어의 사용량을 제한하며, 콘텐츠를 필터링합니다. 여러분의 클라이언트는 단순하게 — 그리고 안전하게 — 남습니다.
9. 코드 리뷰는 관료주의 도구가 아닌 속도 도구입니다
제가 세 명의 주니어 개발자를 멘토링하면서 매주 코드 리뷰를 진행하기 시작했을 때, 스프린트 전반에 걸쳐 보고된 버그가 약 35% 감소했습니다.
모든 버그를 잡아냈기 때문이 아니라 — 지식을 확산시켰기 때문입니다. 한 달 후에는 모두가 저장 시스템이 어디에 있는지, 풀링 규칙(pooling rules)이 왜 존재하는지, 그리고 어떤 '임시 해결책' 패턴을 금지했는지 알고 있었습니다.
리뷰는 작고, 자주, 친절하게 유지하세요. 200줄짜리 리뷰는 실제 피드백을 얻습니다. 2,000줄짜리 리뷰는
- 제품이 3D, AR/VR 또는 실시간 그래픽 환경에서 작동할 때는 Unity를 사용하세요.
- 대부분 UI, 양식(forms), 피드 및 API 호출로 구성될 때는 Flutter를 사용하세요.
- 앱 내부에 3D 또는 AR 순간이 필요한 경우에는 둘 다 사용할 수 있습니다.
가장 좋아하는 도구를 언제 사용하지 말아야 하는지 아는 것이 시니어 레벨의 역량입니다.
요약본
- 재미있는 부분부터 프로토타입을 만드세요 (Prototype the fun first)
- 데이터는 ScriptableObjects에 저장하세요
- 생성되는 모든 것은 객체 풀링(Pool everything that spawns) 하세요
- 가장 성능이 낮은 장치에서 프로파일링을 하세요
- 멀티플레이어 권한(multiplayer authority)은 첫날부터 결정하세요
- 백엔드는 일찍 구축하세요 (Backend early)
- 범위를 줄이고, 품질을 절대 타협하지 마세요 (Cut scope, never quality)
- AI 키는 서버에 두세요
- 작고 빈번한 코드 리뷰를 하세요
- 익숙한 도구가 아닌, 올바른 도구를 선택하세요
현재 저는 Unity Editor용 오픈소스 AI 도구를 만들고 있습니다. 먼저 보고 싶다면 여기에서 저를 팔로우해 주세요.
가장 힘들게 배운 Unity 교훈은 무엇인가요? 댓글에 남겨주세요. 하나도 놓치지 않고 읽겠습니다. 👇
저는 시니어 Unity 엔지니어이자 Flutter 및 AI 앱 개발자인 Dilawar입니다. 이 교훈들 뒤에 숨겨진 게임, 앱, XR 프로젝트들은 dilawarhussain.site에서 확인하실 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기