엔진이 5.7로 올라오면서 기존의 5.5에서 사용하던 Data Build와 이름이 달라졌습니다. 어떻게 달라졌는지 알아보겠습니다.
1. "By the Book" - 전통적인 Cook & Package 방식
전통적인 방식의 핵심은 '느슨한 파일(Loose Files)' 구조입니다. 쿠킹된 개별 애셋 파일(.uasset, .umap)들이 최종 빌드에 거의 그대로 포함되는 형태입니다.
- 쿠킹 (Cooking): 에디터에서 사용되는 원본 애셋(e.g.,
.png,.fbx을 임포트한.uasset)을 각 타겟 플랫폼(e.g., Windows, PS5, Android)에서 즉시 사용할 수 있는 포맷으로 변환하는 과정입니다. 예를 들어, 텍스처는 플랫폼별 하드웨어 압축 포맷(DXT, ASTC 등)으로 변환되고, 셰이더는 특정 그래픽 API(DirectX, Vulkan 등)에 맞는 코드로 컴파일됩니다. - 스테이징 (Staging): 쿠킹된 애셋과 게임 실행에 필요한 엔진 바이너리, 플러그인, 설정 파일 등을 모두 একটি(하나)의 디렉터리(
Saved/StagedBuilds)에 모으는 과정입니다. 이 디렉토리는 최종적으로 배포될 게임의 파일 구조와 동일합니다. - 패키징 (Packaging): 스테이징된 파일들을 최종 배포 형태(e.g., Windows의 경우 Installer, 모바일의 경우
.apk/.ipa)로 묶는 과정입니다. 이 단계에서 파일들을 단순히 복사하거나, 기본적인 압축을 적용할 수 있습니다.
1.1. 내부 구조 및 구현
이 방식의 I/O는 운영체제(OS)의 표준 파일 시스템에 크게 의존합니다.
- 파일 구조:
Content폴더의 구조가 쿠킹된 출력물 폴더에 대부분 유지됩니다. 예를 들어/Content/Characters/MyChar.uasset은/Saved/Cooked/Windows/MyProject/Content/Characters/MyChar.uasset과 같이 유사한 경로에 생성됩니다. - 런타임 동작: 게임 실행 중 애셋을 로드해야 할 때, 엔진은 OS 파일 시스템에 직접 파일 열기(File Open)를 요청합니다. 예를 들어
MyChar를 로드하려면, 파일 시스템은 디스크에서MyChar.uasset파일을 찾아 그 내용을 메모리로 읽어들입니다. 이는 수많은 개별 파일에 대한 I/O 요청을 발생시킵니다.
1.2. 계층 구조별 동작
- 사용자/엔진 계층:
LoadObject()나 비동기 로딩 함수를 통해 애셋 로드를 요청합니다. - 가상 파일 시스템 (IPlatformFile): 엔진은 물리적 파일 위치를 직접 다루지 않고
IPlatformFile이라는 가상 파일 시스템 인터페이스를 통해 파일 I/O를 요청합니다. - OS 파일 시스템 계층:
FWindowsPlatformFile(Windows의 경우)과 같은 구체적인 구현체가 OS의 API(e.g.,CreateFileW)를 호출합니다. - 하드웨어 계층: OS는 디스크 드라이버를 통해 물리적 저장 장치(HDD, SSD)에 접근하여 파일 데이터를 읽습니다. 수많은 파일이 파편화되어 저장된 경우, HDD에서는 헤드 탐색(seek) 시간이 급증하여 심각한 성능 저하를 유발합니다.
2. Pak (Unreal Pak) 파일 시스템
수많은 파일로 인한 I/O 비효율을 해결하기 위해 도입된 시스템입니다. 여러 파일을 하나의 거대한 아카이브 파일(.pak)로 묶어 관리합니다.
Pak 시스템은 여러 파일을 하나의 파일로 묶어 '가상 파일 시스템'을 구축하는 개념입니다. 이를 통해 파일 수를 극적으로 줄여 OS의 파일 핸들링 부하를 줄이고, 데이터 접근을 중앙화하여 로딩 성능을 개선합니다.
- Pak 파일 생성: 쿠킹과 스테이징 과정 이후, 스테이징된 파일들을
UnrealPak.exe유틸리티를 사용하여 하나 이상의.pak파일로 압축하고 아카이브합니다. - 마운트 (Mounting): 게임 시작 시, 엔진은 지정된 경로의
.pak파일들을 '마운트'합니다. 이 과정에서.pak파일 내부에 어떤 파일들이 있는지 목록(인덱스)을 읽어 메모리에 적재합니다.
2.1. 내부 구조 및 구현
.pak 파일은 크게 인덱스(Index)와 데이터(Data) 영역으로 나뉩니다.
- Pak 파일 구조:
- 레코드 (Records): 파일의 끝 부분에 위치하며, 아카이브에 포함된 모든 파일의 메타데이터(경로, 오프셋, 크기, 압축 정보 등)를 담고 있는 인덱스 영역입니다.
- 데이터 블록 (Data Blocks): 실제 파일들의 내용이 순차적으로 저장되는 영역입니다. 각 파일은 압축(e.g., Zlib)될 수 있습니다.
- 푸터 (Footer): 파일의 맨 끝에 위치하며, Pak 파일의 버전, 인덱스 오프셋, 인덱스 크기, 전체 파일의 해시(SHA1) 등 Pak 파일 자체의 정보를 담고 있습니다.
- 런타임 동작 (
FPakPlatformFile):IPlatformFile체인에서FPakPlatformFile은 하위 파일 시스템(e.g., OS 파일 시스템)을 감싸는 래퍼(wrapper) 역할을 합니다.- 파일 요청이 들어오면,
FPakPlatformFile은 먼저 마운트된 모든.pak파일의 인덱스를 확인하여 요청된 파일이 존재하는지 검사합니다. - 파일이 인덱스에 존재하면,
.pak파일의 해당 오프셋으로 직접 이동(seek)하여 압축된 데이터를 읽어온 뒤, 메모리에서 압축을 해제하여 엔진에 전달합니다. - 만약
.pak파일에 없다면, 요청을 하위 파일 시스템으로 전달하여 느슨한 파일(loose file) 중에 있는지 찾아봅니다.
2.2. 계층 구조별 동작
- 사용자/엔진 계층: 애셋 로드를 동일하게 요청합니다.
- 가상 파일 시스템 (
FPakPlatformFile): 파일 요청을 가로챕니다. 메모리에 있는 Pak 인덱스에서 파일 경로를 빠르게 검색합니다. - Pak 파일 접근: 인덱스에서 파일의 위치(오프셋)를 찾으면, OS 파일 시스템에 단일
.pak파일의 특정 범위(range)를 읽도록 요청합니다. 이는 여러 파일을 여는 것보다 훨씬 효율적입니다. - OS 및 하드웨어 계층: 거대한 단일 파일 내에서 특정 위치를 찾는 것은 디스크 헤드 움직임을 최소화하여, 특히 HDD에서 큰 성능 향상을 가져옵니다.
3. Io Store & Zen Streaming
Io Store는 SSD, NVMe와 최신 콘솔 아키텍처에 맞춰 설계된 패키징 및 I/O 시스템입니다. Zen Streaming은 Io Store를 네트워크를 통해 서비스하는 기능입니다.
Io Store는 '데이터 중심' 및 '청크 기반' 아키텍처를 채택했습니다. 에셋이라는 파일 단위가 아닌, 데이터를 해시 기반으로 주소화하고 작은 '청크(Chunk)'로 나누어 관리합니다.
- 주요 특징:
- 콘텐츠 주소화 저장 (Content Addressable Storage): 모든 데이터 청크는 자신의 내용물에 대한 해시(Hash) 값으로 식별됩니다. 이로 인해 동일한 데이터(e.g., 중복된 텍스처)는 단 한 번만 저장되어 패키지 크기가 크게 감소합니다.
- 세분화된 로딩 (Granular Loading): 애셋을 통째로 로드하는 대신, 필요한 부분(e.g., 밉맵 레벨)만 청크 단위로 로드할 수 있습니다. 이는 Nanite, 가상 텍스처링(VT)과 같은 기술의 핵심 기반이 됩니다.
- 최적화된 I/O: 모든 I/O 요청은
FIoDispatcher를 통해 비동기적으로 처리되며, 대량의 작은 요청들을 모아 효율적인 단일 읽기 작업으로 병합합니다. 이는 SSD의 병렬 처리 능력을 극대화합니다. - 암호화 및 압축: 청크 단위로 압축(Oodle Kraken/Zlib) 및 암호화(AES)를 지원합니다.
- Zen Streaming: 개발 중에 사용되는 기능으로,
UnrealZenServer라는 별도의 서버가 Io Store 컨테이너를 호스팅합니다. 게임 클라이언트(PC, 콘솔, 모바일)는 네트워크를 통해 이 서버에 필요한 청크를 요청하여 실시간으로 스트리밍 받습니다. 이는 개발 과정에서 매번 빌드를 디바이스에 배포할 필요 없이 즉시 변경사항을 테스트할 수 있게 하여 반복(iteration) 시간을 혁신적으로 단축시킵니다.
3.1. 내부 구조 및 구현
Io Store는 주로 두 가지 파일 유형으로 구성됩니다.
.ucas(Unreal Content Addressable Storage): 실제 데이터 청크들이 압축된 상태로 저장되는 거대한 컨테이너 파일입니다. 내부에 디렉토리 구조가 없으며, 단순히 데이터 덩어리들의 집합입니다..utoc(Unreal Table of Contents):.ucas파일에 대한 목차(Table of Contents) 파일입니다. 각 청크 ID(FIoChunkId)가.ucas파일의 어느 위치에 어떤 크기로 저장되어 있는지에 대한 정보를 담고 있습니다. 이 파일은 매우 작고 메모리에 효율적으로 매핑되도록 설계되어, 청크 위치를 거의 즉시 조회할 수 있습니다.- 런타임 동작 (
FIoDispatcher):- 애셋 로딩 시스템이 특정 애셋(e.g.,
UTexture)에 필요한 청크 ID 목록을 알아냅니다. - 이 청크 ID들을
FIoDispatcher에 비동기 I/O 요청으로 보냅니다. FIoDispatcher는 이 요청들을 수집하고 우선순위를 정한 뒤, 하위IPlatformFile을 통해.utoc에서 청크 위치를 찾고.ucas에서 데이터를 읽어옵니다.- Zen Streaming이 활성화된 경우,
FIoDispatcher는 로컬 파일 대신 Zen 서버에 네트워크 요청을 보내 청크를 가져옵니다. - 읽어온 압축된 청크는 비동기 작업 큐에서 압축 해제된 후, 애셋 객체를 생성하는 데 사용됩니다.
- 애셋 로딩 시스템이 특정 애셋(e.g.,
3.2. 계층 구조별 동작
- 사용자/엔진 계층 (Nanite, VT 등): 렌더링에 필요한 데이터(e.g., 특정 메시 클러스터, 텍스처 페이지)를 요청합니다. 이는 더 이상 '애셋' 단위가 아닌 '데이터' 단위의 요청입니다.
- 비동기 로딩 시스템: 요청된 데이터를 구성하는 청크 ID들을 식별하여
FIoDispatcher에 전달합니다. FIoDispatcher(I/O 허브): 모든 I/O 요청의 중앙 허브 역할을 합니다. 요청을 최적의 순서로 정렬하고 병합하여 하드웨어의 최대 처리량을 이끌어냅니다.FIoStoreReader/FZenIoStoreReader: 로컬.utoc/.ucas파일을 읽거나, Zen 서버에 네트워크로 청크를 요청합니다.- OS 및 하드웨어 계층:
FIoDispatcher에 의해 최적화된 대규모 순차 읽기(Sequential Read) 요청이 하드웨어로 전달됩니다. 이는 SSD의 성능을 100% 활용하는 데 가장 이상적인 패턴입니다.
4. 비교 분석
| 특징 | Traditional ("By the Book") | Pak File System | Io Store & Zen Streaming |
|---|---|---|---|
| 주요 개념 | 느슨한 파일, OS 파일 시스템 의존 | 파일 아카이브, 가상 파일 시스템 | 콘텐츠 주소화, 청크 기반, I/O 디스패처 |
| I/O 성능 | 매우 나쁨 (특히 HDD에서) | 좋음 (파일 수 감소, 탐색 시간 개선) | 매우 뛰어남 (SSD에 극도로 최적화, 비동기 병렬 처리) |
| 패키지 크기 | 큼 (중복 데이터 많음) | 보통 (압축 지원) | 작음 (전역 중복 제거) |
| 로딩 단위 | 파일 전체 | 파일 전체 | 세분화된 청크 (필요한 부분만) |
| 개발 반복 속도 | 느림 (전체 재배포 필요) | 느림 (전체 재배포 필요) | 매우 빠름 (Zen 서버로 실시간 스트리밍) |
| 주요 사용처 | 레거시 프로젝트, 간단한 앱 | UE4 표준, 모바일, 현세대 이전 콘솔 | UE5 표준, 차세대 콘솔, PC, 대규모 오픈월드 |
| 핵심 기술 | OS fopen |
FPakPlatformFile, 인덱스 기반 조회 |
FIoDispatcher, 해시 기반 조회, .ucas/.utoc |
장단점 및 사용 시나리오
- Traditional 방식:
- 장점: 구조가 가장 단순하여 이해하기 쉽습니다.
- 단점: 성능이 매우 낮고 패키지 관리가 어렵습니다. 현재는 거의 사용되지 않습니다.
- 시나리오: 엔진의 가장 기본적인 동작 원리를 학습하는 교육용 목적 외에는 권장되지 않습니다.
- Pak 파일 시스템:
- 장점: 수많은 파일을 하나로 묶어 관리가 용이하고, 전통 방식 대비 로딩 성능이 크게 향상됩니다. 성숙하고 안정적인 기술입니다.
- 단점: 애셋 단위 로딩만 가능하여 유연성이 떨어지고, 중복 데이터로 인한 용량 비효율 문제가 여전히 존재합니다.
- 시나리오: 모바일 게임이나 중간 규모의 프로젝트, 또는 SSD가 보편화되지 않은 환경을 타겟할 때 여전히 유효하고 좋은 선택입니다.
- Io Store & Zen Streaming:
- 장점: 최고의 I/O 성능, 최소의 패키지 크기, 극도로 빠른 개발 반복 속도 등 모든 면에서 향상된 시스템입니다. Nanite와 같은 최신 기술의 필수 기반입니다.
- 단점: 내부 구조가 복잡하고, 시스템을 완전히 활용하기 위해서는 콘텐츠를 Io Store에 맞게 구성해야 하는 등 학습 곡선이 있습니다.
- 시나리오: PS5, Xbox Series X|S, NVMe SSD를 탑재한 PC 등 고성능 플랫폼을 타겟하는 모든 현대적인 AAA급 게임에 필수적입니다. 대규모 오픈월드 게임 개발 시 사실상 유일한 선택지입니다.
'Unreal' 카테고리의 다른 글
| EOS 보이스 채팅 구현 (0) | 2026.01.05 |
|---|---|
| EOS 보이스 인터페이스 (0) | 2025.12.26 |
| Installed Engine vs Source Build Engine (0) | 2025.12.23 |
| 포스트 프로세스 볼륨 Post Process Volume (1) | 2025.12.19 |
| 레이 트레이싱 Ray Tracing (1) | 2025.12.18 |
