개요

지난 글에서는 Role A로 spec 기반 코어 기능을 구현하고, PixelLab.ai와 GPT를 섞어 캐릭터 애니메이션을 만든 과정을 정리했다.

마지막 날에는 새 기능을 더 만드는 대신 디버깅과 제출용 Web build에 시간을 사용했다. 이때 만난 두 문제는 겉으로 보이는 증상과 실제 원인이 달랐다.

하나는 작은 문턱에서 트라우마가 하늘로 사라지는 문제였고, 다른 하나는 Web build에서 한국어가 보이지 않는 문제였다.

이번 글이 답할 질문은 하나다. AI가 spec을 보고 코드를 만들었는데도, 왜 마지막에는 사람이 코드와 Unity 동작을 직접 이해해야 했을까?


1. 트라우마가 문턱을 밟고 하늘로 올라갔다

게임에서는 특정 상호작용이 끝난 뒤 트라우마가 플레이어를 추격한다. 화면과 음악이 바뀌고, 플레이어는 트라우마를 피해 다음 지점으로 이동해야 한다.

마지막 날 이 추격 Scene을 확인하다 이상한 동작을 발견했다.

트라우마가 작은 문턱에 닿자 갑자기 위로 올라가기 시작했다. 잠깐 튀는 정도가 아니라 계속 상승했고, 결국 화면 밖으로 사라졌다.

처음 화면만 보면 문턱의 Collider가 잘못됐다고 생각하기 쉽다. 하지만 문턱은 직접적인 원인이 아니었다. 문턱은 기존 이동 코드에 남아 있던 점프 행동을 실행시키는 계기였다.

문턱이 트라우마를 밀어 올린 것이 아니라, 문턱을 만난 코드가 트라우마를 계속 올리고 있었다.


2. gravity = 0인데 점프는 남아 있었다

문제 당시 이동 구조를 줄이면 다음과 같았다.

if (shouldJump)
{
    verticalVelocity = 5f;
}

verticalVelocity -= gravity * deltaTime;
position.y += verticalVelocity * deltaTime;

점프가 실행되면 verticalVelocity에 위쪽 속도 5를 넣는다. 정상이라면 매 frame 중력이 이 값을 줄인다.

verticalVelocity -= gravity * deltaTime;

공을 위로 던졌을 때 처음에는 올라가지만 점점 느려지고, 멈춘 뒤 다시 떨어지는 것과 같다. 여기서 verticalVelocity는 지금 위나 아래로 얼마나 빠르게 움직이는지 나타내는 값이고, gravity는 매 frame 그 속도를 아래쪽으로 바꾼다.

그런데 당시 중력에 의해 트라우마가 맵 밖으로 떨어지지 않도록 조정했었던 Parameter는 다음처럼 설정돼 있었다.

gravity = 0f;

식을 그대로 넣어보면 변화량도 0이다.

verticalVelocity = 5
verticalVelocity -= 0 × deltaTime
verticalVelocity = 5

한 번 5가 된 위쪽 속도가 줄어들지 않았다. 그래서 문턱을 만난 순간 점프가 실행되고, 그 뒤에는 같은 속도로 계속 위로 올라갔다.

버그의 원인은 “문턱이 높다”가 아니라, 중력을 끈 이동체에 점프 상태를 남겨둔 것이었다.


3. 값을 조정하지 않고 기능을 제거했다

처음 떠올릴 수 있는 해결은 gravity 값을 다시 올리는 것이다. 그러면 점프한 뒤 다시 내려올 수 있다.

하지만 트라우마가 게임에서 해야 할 일을 다시 생각했다.

  • 플레이어를 계속 추격한다.
  • 지형의 작은 높이 차이 때문에 멈추지 않는다.
  • 주변 물체에 밀리거나 낙하해서 추격을 놓치지 않는다.
  • 점프 타이밍을 플레이어에게 보여줄 필요가 없다.

트라우마는 일반적인 platform character가 아니었다. 중력, 착지, 점프, 벽타기까지 가진 범용 이동 로직이 실제 역할에 필요하지 않았다.

그래서 gravity를 조절해 기존 구조를 살리는 대신, 점프와 중력 로직 자체를 제거했다. 최종 TraumaChaseActor는 중력 없는 kinematic body를 사용하고, 주변 지형의 영향을 받지 않은 채 플레이어의 위치를 향해 이동한다.

저장소에도 이 변화가 fix(trauma): 중력 없이 플레이어를 추적한다는 Git 기록과 회귀 테스트로 남아 있다.

수정 후보 남는 문제
gravity 값 조절 필요하지 않은 점프·착지·벽타기 상태가 계속 남음
문턱 Collider 수정 다른 지형에서 같은 분기가 다시 실행될 수 있음
점프·중력 로직 제거 트라우마의 실제 역할인 추격만 남음

값을 조정해서 범용 이동 로직을 살리는 대신, 트라우마의 실제 역할에 필요하지 않은 기능을 제거했다.


4. Web build에서 한국어가 사라졌다

추격 문제를 고친 뒤 제출을 위해 Web build를 진행했다. 이번에는 게임 속 한국어가 아예 보이지 않았다.

처음에는 WebGL에서 한국어가 제대로 표시되지 않는 문제처럼 보였다. 실제 원인은 WebGL 자체가 아니었다.

프로젝트에 한국어 글자를 가진 font asset이 처음부터 빠져 있었다.

Unity Editor는 개발 PC의 환경 안에서 실행된다. 그래서 프로젝트 안에 필요한 font가 없어도 Editor에서는 문제가 바로 드러나지 않을 수 있다. 반면 Web build는 빌드에 포함된 asset만 가지고 브라우저에서 실행된다. 한국어 glyph가 포함된 font가 없으면 글자를 그릴 재료도 없다.

수정은 두 단계였다.

  1. NanumGothic-Regular.ttf를 프로젝트의 font resource로 추가했다.
  2. 기존 uGUI Text와 world-space TextMesh, 실행 중 생성되는 HUD에 그 font를 다시 mapping했다.

프로젝트의 QA에는 현대 한글 glyph 전체와 UI 기호의 누락 여부, 로드된 Text component에 font가 적용되는지를 검사한 기록도 남아 있다.

Unity Editor에서 동작하는 것과 실제 제출 가능한 build가 되는 것은 다른 단계였다.


5. 코드는 Unity 프로젝트의 일부일 뿐이었다

처음에는 Unity 프로젝트에 AI orchestration을 적용하면 비교적 쉽게 게임을 만들 수 있을 것이라고 생각했다.

실제로 AI는 spec을 읽고 코드를 빠르게 만들었다. 상태 전환, 이동, 상호작용, 저장 같은 기능의 시작점을 짧은 시간에 만들 수 있었다.

하지만 Unity 프로젝트는 코드만으로 이루어지지 않는다.

Unity 구성 코드와 만나는 지점
Scene 어떤 Object가 언제 로드되는지 정한다.
Prefab Component와 기본 설정을 묶는다.
Collider 이동과 충돌이 시작되는 조건을 바꾼다.
Inspector Parameter 같은 코드의 속도, 중력, 범위를 바꾼다.
Asset Sprite, animation, font, audio가 실제 화면을 만든다.
UI Scene load 시점과 runtime 생성 순서의 영향을 받는다.

AI가 작성한 코드, 씬 위에서 Prefab이나 Parameter를 수정하면 예상하지 못한 곳에서 버그가 생겼다. gravity = 0과 남아 있던 점프 로직의 조합이 그랬고, Editor에서는 보였던 한국어가 build에서 사라진 일도 그랬다.

문제가 생기면 결국 코드를 읽고, Component가 어디에 붙었는지 확인하고, Inspector 값과 Scene의 Collider까지 직접 이해해야 했다.

AI라는 툴 자체가 내가 아는 만큼 잘 이용할 수 있었다.

AI가 대신 알고 있는 만큼 개발할 수 있는 게 아니라, 내가 이해하고 있는 만큼 AI를 잘 사용할 수 있었다.


6. 다음에는 AI를 구현 과정의 조언자로 써본다

이번 프로젝트의 흐름은 다음에 가까웠다.

내가 spec 작성
  → AI가 구현
  → 내가 적용
  → 내가 디버깅

이 방식은 빠르게 코드를 얻을 수 있지만, 중간의 “왜 이렇게 구현했는가?”를 놓치기 쉽다. 문제가 생긴 뒤에야 AI가 만든 구조를 거꾸로 공부하게 된다.

다음 프로젝트에서는 순서를 바꿔보려 한다.

내가 직접 구현
  → AI에게 개념과 구현 방법을 질문
  → 왜 그 방법을 쓰는지 이해
  → 직접 코드 작성

AI에게 완성 코드를 먼저 요청하기보다 다음을 물어볼 생각이다.

  • 이 기능은 Unity에서 어떤 Method나 Component로 구현하는가?
  • 왜 그 방법을 사용하는가?
  • 왜 이것이 관례적으로 쓰이는가?
  • 다른 구현법과 trade-off는 무엇인가?
  • 자주 발생하는 문제는 무엇인가?

코드를 받지 않겠다는 뜻은 아니다. 먼저 선택지와 이유를 이해하고, 내가 작성한 코드에서 막힌 부분을 함께 보는 방식에 가깝다.

즉 AI를 생성형 코드 작성 도구보다 구현 과정의 조언자로 사용해보려 한다.

다음에는 “이 코드를 써줘”보다 “왜 이 방법을 쓰는지 알려줘”를 먼저 묻는다.


정리

  • 추격 버그의 증상: 트라우마가 작은 문턱을 만난 뒤 계속 상승해 화면 밖으로 사라졌다.
  • 실제 원인: 문턱은 점프를 실행시킨 계기였고, gravity = 0이라 위쪽 속도가 줄어들지 않았다.
  • 수정 방향: gravity 값을 조절하지 않고 트라우마에 필요하지 않은 점프·중력 로직을 제거했다.
  • Web build 문제: WebGL 자체가 아니라 프로젝트에 한국어 font asset이 빠져 있었다.
  • 빌드 수정: 한국어 font를 추가하고 기존 Text component와 runtime HUD에 다시 mapping했다.
  • 생각의 변화: AI가 코드를 대신 아는 만큼이 아니라, 내가 Unity를 이해하는 만큼 AI를 잘 사용할 수 있었다.
  • 다음 방식: AI에게 완성 코드를 먼저 맡기기보다 구현 방법, 이유, trade-off, 흔한 문제를 묻고 직접 구현해본다.

참고 자료

한줄 평

  • AI가 코드를 빠르게 만들어줬지만, 마지막 버그를 고친 것은 결국 내가 코드와 Unity 동작을 이해한 만큼이었다.ㅠㅠ