Unity
시간을 되돌리는 해파리 : 하루만에 개발 완료하기
곽*환··수정됨 2026.10.09
시작하며
화면 속 해파리에게 먹이를 주면 자라서 성체가 되고, 상처를 주거나 굶기면 다시 폴립으로 돌아갑니다. 위기가 오면 어린 시절로 돌아가는 해파리의 생활사를 관람객이 직접 체험하는 콘텐츠입니다.
이 콘텐츠는 하루만에 개발해야 했습니다. 일정이 촉박하여 기획을 받은 날 개발을 끝내고, 그 다음날 수정사항을 받아 수정해야 했습니다.
하루짜리 일정에서 가장 무서운 것은 버그입니다. 현장에서 발견되는 버그 하나가 남은 시간을 다 잡아먹기 때문입니다. 이 글은 짧은 일정 안에서 빠르면서도 정확하게 개발하려고 제가 쓴 방법을 정리한 기록입니다.
1. 먼저 화면부터 쪼갰습니다
코드를 작성하기 전에 콘텐츠에 들어갈 패널(화면)을 모두 나열하고, 어디서부터 어디로 흐르는지를 먼저 정리했습니다.
정리하고 보니 화면은 모두 10개였습니다.
기본 흐름: 시작 화면, 폴립 화면, 성체 화면
먹이주기 게임: 인게임 시작, 인게임 메인, 인게임 실패, 인게임 굶주림
상처 분기: 상처받음 화면, 스트레스 화면
복귀: 폴립으로 변경 화면

흐름도를 그리고 나니 구조가 단순하다는 것이 보였습니다. 관람객이 직접 고르는 분기는 성체 화면 한 곳 뿐입니다. 나머지 전환은 먹이 횟수를 채우거나, 일정 시간이 지나면 자동으로 일어납니다.
다행히 콘텐츠의 볼륨 자체는 크지 않았습니다. 대신 자동 전환이 많아서 타이머가 꼬이면 화면이 엉뚱한 곳으로 넘어갈 위험이 컸습니다. 그래서 분석 단계에서 다음 두 가지를 원칙으로 정했습니다.
화면은
MainPageTypeenum 하나로 관리하고, 전환은 반드시UI_Main.Change()한 곳만 거칩니다.화면마다 도는 타이머는 화면이 다시 열릴 때 이전 것을 반드시 취소합니다.

먹이 횟수와 화면별 대기 시간은 코드에 적지 않고 StreamingAssets의 설정 파일(ContentConfig)에서 읽도록 했습니다. 현장 설치 중에 "먹이를 조금 덜 줘도 자라게 해 주세요" 같은 요청이 와도, 다시 빌드하지 않고 값만 바꾸면 됩니다. 당일 납품 일정에서는 이 차이가 큽니다.
2. 빠를수록 읽기 쉬운 코드가 필요했습니다
시간이 없을수록 코드는 대충 쓰기 쉽습니다. 하지만 하루짜리 개발에서는 다시 읽는 시간이 쓰는 시간보다 더 많이 듭니다. 버그를 잡으려면 방금 쓴 코드를 몇 번이고 다시 읽어야 하기 때문입니다.
그래서 제가 정리해 둔 C# 코딩 규칙(Coding Rule.txt)을 처음부터 그대로 적용했습니다. 핵심은 '한눈에 의도가 보이는 코드'입니다.
접근 지정자를 항상 명시합니다. 기본 접근 수준을 추측할 필요가 없습니다.
[SerializeField]와 필드 선언을 다른 줄에 씁니다. Inspector에 노출되는 값을 세로로 훑으며 바로 찾을 수 있습니다.이름에 타입과 역할이 드러나는 접미사를 붙입니다.
GameObject는Obj, bool은is접두사를 씁니다.bool 판별은
== true,== false로 명시합니다. 조건을 거꾸로 읽는 실수를 막습니다.제어문 본문은 항상 중괄호로 감싸고, 한 줄에 한 문장만 씁니다. 식 본문(
=>)과$문자열 보간은 되도록 쓰지 않습니다.

규칙 하나하나는 사소해 보입니다. 하지만 10개 패널 스크립트가 모두 같은 모양으로 쓰여 있으니, 어느 파일을 열어도 바로 읽혔습니다. 다른 사람이 코드를 대신 확인해 줄 때도 설명이 거의 필요 없었습니다.
3. 뼈대는 ContentFrameBuilder(Fade)로 한 번에
전시 콘텐츠는 대부분 비슷한 뼈대를 가집니다. 여러 패널이 있고, 패널 사이를 전환하고, 일정 시간 입력이 없으면 시작 화면으로 돌아갑니다. 저는 이 반복 작업을 자체 프레임워크인 _KMHFramework의 ContentFrameBuilder로 자동화해 두었습니다.

에디터 메뉴 KMHModule > Content Frame Builder에서 Fade 탭을 고르고 패널 이름 10개만 입력하면 다음 작업이 자동으로 진행됩니다.
스크립트 생성:
ContentHandler,UI_Base,UI_Main, 패널별 스크립트를 만듭니다.컴파일 대기: 스크립트 컴파일이 끝나면 씬 구성을 이어서 실행합니다.
씬 구성: Canvas 아래에 패널을 만들고, 패널마다
UI_AlphaTweener,ScaleTweener,CanvasGroup,Canvas,GraphicRaycaster를 붙입니다. 페이드 시간과 커브 값은 미리 맞춰 둔 기본값으로 채워집니다.참조 연결:
UI_Main의 패널 필드와 각 패널의main필드를SerializedObject로 자동 연결합니다. 손으로 드래그할 일이 없어 연결 누락으로 생기는NullReferenceException이 원천적으로 사라집니다.공통 모듈 배치:
SceneInitializer,InputHandler, 설정 파일 리더 같은 공통 오브젝트를 씬에 배치합니다.
Fade 모드의 핵심은 UI_Main의 전환 로직입니다. 새 패널을 먼저 페이드로 띄우고, 페이드가 끝난 뒤에 이전 패널을 끕니다. 전환 중에 다른 전환이 들어오면 이전 페이드를 취소합니다.

뼈대를 만드는 데 드는 시간이 거의 0이 되었고, 남은 시간은 해파리 콘텐츠 자체의 로직에 쓸 수 있었습니다.
4. 움직임은 자체 Tween 라이브러리로
패널 페이드뿐 아니라 먹이를 줄 때의 이펙트, 상처받는 연출, 성장 완료 연출까지 이 콘텐츠에는 작은 움직임이 많습니다. 저희는 이 움직임을 외부 에셋 대신 _KMHFramework에 직접 만들어 둔 Tween 라이브러리로 처리했습니다.
구조는 단순합니다. BaseTweener가 duration과 AnimationCurve를 가지고, 위치·스케일·회전·알파·이미지 색상 같은 대상별 Tweener가 이를 상속합니다. 컴포넌트를 붙이고 Inspector에서 커브만 그리면 움직임이 완성되므로, 디자이너와 연출을 맞추기도 쉬웠습니다.

마치며
하루라는 일정은 짧았지만, 개발은 예정보다 빨리 끝났고 당일 납품까지 마칠 수 있었습니다. 돌아보면 그날 새로 만든 것보다, 그 전에 만들어 둔 기능들이 일정을 지켜 주었습니다.
화면 분석을 먼저: 10개 패널과 전환 조건을 먼저 정리하니 구현할 범위가 분명해졌습니다.
읽기 쉬운 코딩 룰: 모든 스크립트가 같은 모양이어서 다시 읽고 검증하는 시간이 줄었습니다.
미리 만들어 둔 도구: ContentFrameBuilder(Fade)로 뼈대를, 자체 Tween 라이브러리로 움직임을 빠르게 갖췄습니다.
급한 일정은 앞으로도 계속 생길 것입니다. 그때마다 처음부터 만들지 않도록, 반복되는 작업은 지금처럼 프레임워크에 도구로 쌓아 두시길 권합니다.
읽기 도구
약 7분 읽기
이 글이 도움이 되었나요?
Work with GIWorks
프로젝트에 GIWorks의 경험이 필요하신가요?
전시·콘텐츠·엔지니어링 프로젝트의 아이디어와 고민을 들려주세요. 필요한 기술과 실행 방법을 함께 찾겠습니다.
문의하기