개발자 면접 공부/언리얼 엔진

언리얼 UAT, UBT, UHT, UnrealPak 이해

chogyujin 2025. 12. 5. 15:01
728x90

1. 개요

오늘은 언리얼 엔진의 빌드 과정 중 UAT, UBT, UHT, UnrealPak에 대해 알아보겠습니다.


2. 얘네들은 왜 나눠놨을까?

언리얼 엔진이 UAT, UBT, UHT, UnrealPak으로 도구를 쪼개놓은 가장 큰 이유는 역활 분담 및 효율성 때문

 

게임 엔진은 단순히 코드를 실행 파일로 만드는 것 뿐만이 아니라, C++의 한계를 넘고, 복잡한 빌드 과정을 관리, 수만 개의 파일을 압축, 이 모등 과정을 자동화 하기 때문입니다.

 

아래는 각 UAT, UBT, UHT, UnrealPak에 대한 설명입니다.


3. UAT

언리얼 엔진의 총감독 역할을 하는 도구입니다.
UBT(컴파일), UHT(헤더 분석), UnrealPak(압축) 같은 전문가들을 지휘해서, 게임 제작의 시작부터 끝까지(배포)를 자동으로 처리해 주는 도구입니다.

1. 역할: "모든 공정의 자동화 (Automation)"

게임 하나를 완성해서 폰이나 PC에 깔려면 수많은 단계를 거쳐야 합니다. 사람이 이걸 수동으로 하면 실수투성이가 되지만, UAT는 명령어 한 줄(BuildCookRun)로 이 모든 걸 순서대로 처리합니다.

UAT가 지휘하는 'BuildCookRun' 과정

  1. Build (빌드):
    • UBT를 시켜서 C++ 코드를 컴파일해라! (.exe 생성)
  2. Cook (쿠킹):
    • 에디터를 켜서 텍스처랑 모델을 안드로이드/PC용으로 변환해라! (.uasset 변환)
  3. Stage (스테이징):
    • 만들어진 실행 파일(.exe)과 구운 에셋(.uasset)을 한 폴더(Saved/StagedBuilds)에 예쁘게 모아라!
  4. Package (패키징):
    • UnrealPak을 시켜서 모아둔 파일들을 하나로 압축해라! (.pak 생성)
  5. Deploy (배포/설치):
    • (모바일의 경우) USB로 연결된 폰에 자동으로 설치해라! (adb install ...)
  6. Run (실행):
    • 설치된 게임을 켜서 잘 돌아가는지 확인해라!

👉 결론: 개발자가 "빌드해줘"라고 버튼 한 번 누르면, UAT가 뒤에서 저 6단계를 혼자 북 치고 장구 치고 다 하는 겁니다.

2. 왜 UBT랑 따로 만들었을까? (UBT vs UAT)

가장 많이 헷갈리는 부분인데, 역할이 완전히 다릅니다.

  • UBT (Unreal Build Tool): "코드(C++)만" 신경 씁니다.
    • "이 소스 코드를 컴파일해서 실행 파일(Binaries)을 만들어라."
    • 딱 여기까지만 합니다. 에셋(텍스처)이나 패키징은 모릅니다.
  • UAT (Unreal Automation Tool): **"프로젝트 전체"**를 신경 씁니다.
    • "UBT야 코드를 빌드해. 에디터야 에셋을 구워. 그리고 이걸 폰에 설치해."
    • 코드뿐만 아니라 콘텐츠, 파일 복사, 플랫폼별 설치 과정까지 관리합니다.

비유하자면:

  • UBT: 자동차 엔진 조립 담당 팀장.
  • UAT: 자동차 조립, 도색, 포장, 트럭에 실어서 대리점까지 배달하는 전체 공정 총괄 이사.

3. 플랫폼별 복잡함 해결 (Platform Abstraction)

UAT가 진짜 빛을 발하는 순간은 멀티 플랫폼(안드로이드, iOS, 콘솔) 개발을 할 때입니다.

  • 안드로이드: APK 서명해야 하고, adb로 설치해야 하고, OBB 파일 나눠야 함.
  • iOS: 프로비저닝 프로파일 체크해야 하고, IPA 파일로 서명해야 함.
  • 콘솔(PS/Xbox): 각 회사만의 보안 툴을 돌려야 함.

이 복잡한 과정이 플랫폼마다 다 다른데, UAT는 이걸 다 알고 있습니다. 개발자는 그냥 -targetplatform=Android 라고만 적어주면, UAT가 알아서 안드로이드 SDK를 찾아서 처리해 줍니다.


4. UBT

UAT가 "게임 배포 전체"를 총괄한다면, **UBT는 오직 "소스 코드를 실행 파일(.exe/dll)로 만드는 작업"**에만 미친 듯이 집중하는 전문가입니다.

우리가 Visual Studio에서 Ctrl + Shift + B (빌드)를 누르는 순간, 실제로는 UBT가 깨어나서 일을 시작합니다.

1. 역할: 복잡한 "설계도" 해석 (.cs 파일)

일반적인 C++ 프로젝트는 복잡한 설정창(Project Settings)에서 포함 디렉토리나 라이브러리를 세팅합니다. 하지만 언리얼은 C# 스크립트로 이 설정을 관리합니다.

UBT는 우리가 작성한 C# 설정 파일들을 읽어서 "아, 이 모듈은 저 모듈이 필요하구나"라고 의존성을 파악합니다.

  • Target.cs: "무엇을 만들 것인가?" (게임이냐? 에디터냐? 서버냐?)
  • Build.cs: "이 모듈엔 뭐가 필요한가?" (내 플러그인은 Core, Engine 모듈을 쓴다!)

UBT는 이 파일들을 읽어서 "누가 누구를 참조하는지" 족보를 정리합니다.

2. 역할: "통역사(UHT)" 먼저 투입시키기

UBT는 컴파일을 시작하기 전에 가장 먼저 **UHT (Unreal Header Tool)**를 호출합니다.

  1. UBT: "야, 컴파일하기 전에 UHT 너 가서 매크로(UCLASS 등) 번역해놔."
  2. UHT: (헤더 파일들을 훑고 .generated.h 파일을 만듦)
  3. UBT: "번역 끝났어? 오케이, 이제 진짜 컴파일 시작한다."

즉, UBT가 없으면 UHT도 실행되지 않고, 리플렉션 시스템도 작동하지 않습니다.

3. 역할: "컴파일러(MSVC, Clang)"에게 명령 내리기

이게 제일 중요합니다. UBT 자체는 컴파일러가 아닙니다. UBT는 지휘관이고, 실제 일(기계어 변환)은 **Visual Studio의 컴파일러(MSVC)**나 안드로이드용 Clang 등이 합니다.

  • UBT의 명령: "야 MSVC! 지금부터 MyActor.cpp랑 MyGameMode.cpp 컴파일해. 아, 그리고 저기 있는 Engine 라이브러리랑 링크(Link)도 하고. 옵션은 최적화(Optimization) 켜고!"

Visual Studio의 '빌드' 버튼은 사실 껍데기일 뿐이고, 내부적으로는 UBT 명령어를 실행시키는 버튼입니다.

4. 역할: "유니티 빌드(Unity Build)"로 속도 올리기

소스 파일(cpp)이 1000개가 있다고 칩시다. 이걸 하나씩 컴파일하면 파일을 열고 닫는 시간 때문에 엄청 오래 걸립니다.

UBT는 똑똑하게도 여러 개의 .cpp 파일을 하나의 거대한 .cpp 파일로 합쳐서(Include) 한 방에 컴파일해버립니다. 이것을 Unity Build라고 부릅니다.

  • 효과: 빌드 속도가 획기적으로 빨라집니다.
  • 단점: 가끔 "이 헤더 파일 include 안 했는데 왜 되지?" 하는 실수를 유발하기도 합니다. (다른 파일이랑 합쳐지면서 우연히 포함됨)

🧪 개발자가 UBT와 마주치는 순간

우리가 직접 UBT를 켤 일은 거의 없지만, 이 두 파일을 만질 때 사실상 UBT와 대화하는 것입니다.

파일 이름 역할 UBT에게 하는 말
MyGame.Target.cs 전체 빌드 설정 "UBT야, 이번엔 **'에디터용(Editor)'**으로 빌드해줘!"
MyModule.Build.cs 모듈 의존성 설정 "UBT야, 내 모듈은 **'AIModule'**이랑 'UMG' 기능이 필요해. 갖다 써줘."

5. UHT

UHT는 C++ 코드가 언리얼 엔진 시스템(블루프린트, 가비지 컬렉션 등)과 대화할 수 있도록 중간에서 통역해 주는 도구 입니다.

1. 역할: "리플렉션(Reflection) 데이터 생성"

이게 UHT 존재의 알파이자 오메가입니다.

  • 문제점: 원래 C++ 언어는 "자기 성찰" 능력이 없습니다. 실행 중에 "내 클래스 이름이 뭐지?", "내 변수 중에 Health라는 게 있나?" 하고 물어봐도 C++은 모릅니다. 컴파일되면 그냥 기계어 덩어리가 되니까요.
  • 언리얼의 필요성: 그런데 언리얼 엔진은 이게 꼭 필요합니다.
    • 가비지 컬렉션(GC): "메모리 청소해야 하는데, 이 객체가 누구랑 연결돼 있는지 알아야 함."
    • 블루프린트: "C++ 변수 Score를 에디터에서 보여줘야 함."
    • 네트워크: "이 변수 값이 바뀌면 서버에 알려줘야 함."
  • UHT의 해결책: UHT는 컴파일러(Visual Studio)가 돌기 전에 먼저 실행돼서, C++ 헤더 파일(.h)을 싹 훑습니다. 그러다 UCLASS, UPROPERTY, UFUNCTION 같은 매크로를 발견하면, "아! 이건 엔진이 알아야 하는 정보구나!" 하고 따로 기록해 둡니다.

2. 결과물: "마법의 .generated.h 파일"

C++ 코드를 짜다 보면 헤더 파일 맨 위에 #include "MyActor.generated.h" 라는 줄을 보셨을 겁니다. 이 파일은 내가 만든 게 아니죠?

바로 UHT가 만들어준 파일입니다.

  1. 개발자: UPROPERTY(EditAnywhere) int32 Health; 라고 적음.
  2. UHT: 이걸 읽고 "Health 변수는 에디터에서 수정 가능해야 함"이라는 정보를 담은 C++ 코드를 몰래 생성함. (.generated.h와 .gen.cpp 파일 생성)
  3. 컴파일러: 원본 코드와 UHT가 만든 코드를 합쳐서 진짜 빌드를 함.

결론: UHT가 없으면 .generated.h 파일이 안 만들어지고, 그럼 빌드 자체가 안 됩니다.

3. 개발자가 UHT와 대화하는 법 (매크로)

우리가 UHT에게 "이거 호구 조사 해가세요~" 하고 알려주는 신호가 바로 언리얼 매크로들입니다.

매크로 UHT에게 하는 말 (의미)
UCLASS() "이 클래스는 언리얼 객체야. GC랑 블루프린트에서 쓸 수 있게 등록해 줘."
UPROPERTY() "이 변수는 에디터에 노출하거나 네트워크 동기화가 필요해." (GC 등록도함)
UFUNCTION() "이 함수는 블루프린트에서 호출할 수 있게 해줘."

6. Unreal Pak

UnrealPak은 게임에 들어가는 수만, 수십만 개의 파일(텍스처, 모델, 사운드 등)을 단 하나의 거대한 파일(.pak)로 압축하고 뭉치는 역할을 담당합니다.

1. 역할: "로딩 속도 최적화 (I/O Performance)"

이게 UnrealPak을 쓰는 가장 큰 이유입니다.

  • 문제점 (낱개 파일):
    • 게임 폴더 안에 Texture_01.uasset, Sound_02.uasset... 이렇게 파일이 5만 개가 있다고 상상해 보세요.
    • 게임을 켤 때 하드디스크(HDD/SSD)는 이 5만 개의 파일을 찾기 위해 헤드를 5만 번 움직여야 합니다. (랜덤 액세스 발생)
    • 결과: 로딩 시간이 엄청나게 길어집니다.
  • UnrealPak의 해결책:
    • 5만 개의 파일을 **Game.pak**이라는 하나의 파일로 이어 붙입니다.
    • 이제 하드디스크는 파일 하나만 쭉 읽으면 됩니다. (시퀀셜 액세스)
    • 결과: 로딩 속도가 비약적으로 빨라집니다.

2. 역할: "압축 및 용량 절감 (Compression)"

  • 모바일 게임이나 콘솔 게임은 용량 제한이 중요합니다.
  • UnrealPak은 파일들을 뭉칠 때 Zlib이나 Oodle 같은 강력한 압축 알고리즘을 사용해서 용량을 확 줄여줍니다.
  • 개발 폴더에서는 10GB였던 게임이, 패키징 후에는 5GB가 되는 마법이 여기서 일어납니다.

3. 역할: "보안 및 암호화 (Security)"

  • 게임 에셋(캐릭터 모델, 텍스처)을 그냥 폴더에 넣어두면, 유저가 쉽게 열어서 수정하거나 빼갈 수 있겠죠?
  • UnrealPak은 .pak 파일을 만들 때 AES 암호화 키를 걸 수 있습니다.
  • 이렇게 하면 해커가 .pak 파일을 열어보려 해도 암호화되어 있어 내부 데이터를 쉽게 볼 수 없습니다.

🧪 개발자가 UnrealPak과 마주치는 순간

보통은 UAT가 알아서 UnrealPak을 호출하기 때문에 직접 명령어를 칠 일은 없지만, 이런 상황에서 중요하게 다뤄집니다.

  1. 패치/DLC 제작 (Chunking):
    • 게임을 업데이트할 때 전체를 다시 받는 건 비효율적입니다.
    • UnrealPak을 이용해 "변경된 파일만 모아서" Patch_01.pak을 따로 만듭니다.
    • 유저는 이 작은 .pak 파일만 다운로드하면 업데이트가 끝납니다.
  2. 모딩(Modding) 지원:
    • 유저들에게 게임을 수정하게 해주고 싶다면, UnrealPak을 이용해 유저가 만든 에셋을 .pak으로 묶어 게임에 로드하게 할 수 있습니다.

7. 요약 표

 

도구 이름 약어 풀이 핵심 역할 (한 줄 요약) 비유 (공장) 주요 기능 개발자가 마주치는 파일
UAT Unreal Automation Tool 전체 공정 총괄 및 배포 현장 소장님

(총감독)
• 빌드, 쿠킹, 패키징, 배포 자동화

• 플랫폼별(안드로이드, iOS 등) 설치 관리

• 젠킨스/CI 서버와 연동
(거의 없음)

주로 커맨드 라인이나

CI 스크립트
UBT Unreal Build Tool 소스 코드 컴파일 지휘 공장장

(설계/조립)
• 모듈 의존성 계산 (Target.cs, Build.cs)

• UHT 먼저 호출

• 컴파일러(MSVC, Clang)에 명령 하달
*.Target.cs

*.Build.cs
UHT Unreal Header Tool C++와 엔진 간 통역 통역사

(호구조사)
• 리플렉션 데이터 생성

• 매크로(UCLASS, UPROPERTY) 분석

• .generated.h 파일 생성
*.h (헤더 파일)

*.generated.h
UnrealPak Unreal Pak 파일 압축 및 패키징 이삿짐 센터

(포장)
• 수만 개의 파일을 하나로 뭉침 (.pak)

• 로딩 속도 최적화 및 용량 압축

• 암호화 및 패치(Chunk) 생성
.pak

DefaultPaks.ini