공부/Unreal Engine 4

UE4 Mounting Pak File

Lero God 2020. 7. 22. 23:53

UE4에서 pak 파일을 어떻게 마운팅 하는지, 마운팅이 뭔지에 대해 글을 번역한 거다 :)

 


FPakPlatformFile은 pak에 대한 처리를 한다. FPakEntry은 uasset 한 개와 연결되있고, FPakFile은 pak 파일 한 개와 연결되있다.


FPakPlatformFile은 FPakFile 배열을 갖고 있고 각 FPakFile은 여러 개의 FPakEntry를 갖고 있다.


FindFileInPakFiles란 함수를 보면 알 수 있듯이 인자로 찾을 파일 이름과, FPakEntry, FPakFile 포인터를 넘겨준다.


만약 파일을 찾았다면 FPakEntry 포인터엔 asset에 대한 정보가 들어가고 FPakFile 포인터엔 asset을 찾은 pak에 대한 정보가 들어간다.


이 특정한 FPakEntry을 찾은 후엔 asynchronous read handle(비동기적 읽기 핸들?)을 돌려준다.

 

FPakPlatformFile

FPakListEntry는 ReadOrder와 PakFile이 있는데, TArray<FPakListEntry> PakFiles은 모든 마운트 된 pak 파일들을 저장하기 위한 컨테이너다. 이 pak 파일들은 ReadOrder에 따라서 정렬된다.

 

FPakFile 

pak 파일 안에는 다수의 리소스 파일들이 들어있다. 모든 리소스 파일들은 Files에 저장되는데 각자마다 인덱스가 있다!

TMap 인덱스는 FPakDirectory 경로와 매핑되있다. 또 각 리소스 파일 이름과 인덱스 번호도 매핑된다.

정리하자면, 파일을 읽기 위해서 파일 이름을 인자로 넘겨주면, 폴더 경로 + 특정 파일 이름으로 나눠진다.
그 다음 폴더 경로 + 특정 파일 이름을 매핑해 인덱스를 얻는다. 이제 FPakEntry가 어떤 파일인지 알 수 있다 :)

 

FPakEntry

FPakEntry는 pak 파일 안에 저장된 한 개의 리소스이다. FPakEntry는 리소스의 크기와 pak 파일 안에 어디 있는지 알기 위한 offset이 있당

 

FPakPlatformFile의 초기화 과정 (pak 파일을 찾고 마운트 하는 과정)

UE4는 3개의 특정한 폴더들의 경로에서 마운트할 pak 파일들을 찾는다.
이 3개의 폴더 경로가 UE4에 하드 코딩 되있음.

 

    FPaths::ProjectContentDir() - 프로젝트/Content/Paks
    FPaths::ProjectSavedDir() - 프로젝트/Saved/Paks
    FPaths::EngineContentDir() - Engine/Content/Paks  

  

pak 파일들을 마운팅 하는 과정은 총 3가지다:

        폴더에서 pak파일을 찾는다
        마운트된 pak 파일을 찾는다
        특정한 한 개의 pak 파일을 마운트한다    

 

특정한 한 개의 pak 파일을 마운트하기 위해선, 이미 마운트된 pak 파일과 비교를 한 후에, 반복적으로 마운트 되는 pak 파일을 필터링한다. (pak 파일 중복 마운트 방지하기 위함인 듯)
그 다음엔 pak 파일을 읽을 순서가 있어야 한다. pak의 순서는 파일 디렉토리에 따라 정해지는데, Content 디렉토리 밑에 이쓴 파일들이 제일 우선 순위가 높다.
이제 Mount 함수에 팩 파일 이름과 pak 우선 순위를 넘기면 된다.

 

Mount

pak 파일을 찾은 후엔 마운팅을 한다. 마운팅은 pak 안에 들어있는 컨텐츠들이 있는 경로를 생성한 후에 PakFiles에 추가시키는 거라고 보면 된다.

파일을 찾을 땐, 생성된 pak 파일의 경로를 인덱스를 통해 검색해 파일이 있는지 없는지 확인한다.

새로운 FPakFile을 생성하고, 우선 순위를 정해준 뒤 PakFiles에 추가시키면 된다.    

 

마운팅은 3가지의 단계로 나뉘어진다 :
        1. FPakFile 생성
        2. 패치 파일이면 우선 순위를 높임
        3. FPakPlatformFile에 FPakFile을 추가시키고 정렬

 

 

1. FPakFile 생성

 

pak 파일의 정보가 있는 공간 과 파일 인덱스가 있는 부분을 로딩한다.(pak 파일 안에서)

몇 개의 파일이 저장되어있는지 등의 정보도 알아낸다. 이 파일들에 대한 경로-파일 이름-인덱스 구조를 생성한다. Initialize 함수에서 가장 먼저 해야 할 일은 pak 파일에서 pak 파일에 대한 정보 부분을 읽는 것이다.

(pak 파일은 파일 리소스 구간, 파일 인덱스 구간, pak 파일 정보 구간, 총 3가지 구간으로 나누어짐)
FPakInfo에 저장되는 pak 파일 정보 구간은 pak 파일 전체에 대한 정보가 들어있다.

pak 파일 정보 구간은 pak 파일의 맨 마지막에 있기 때문에 pak 파일 크기에서 FPakInfo를 빼면 FPakInfo의 offset이 나온다. pak 파일의 정보 구간을 읽었으면, 이젠 인덱스의 갯수와, offset 등의 정보를 얻을 수 있다.


이제 다음은 파일 인덱스 구간을 읽을 차례다. 이 구간을 읽으면 첫 부분이 MountPoint와 NumEntries이다.

그 다음 Index의 TArray를 읽는다.

파일 인덱스 구간을 읽었으면 파일 리소스 구간을 읽으면 된다.

처음엔 리소스 파일의 이름을 읽어서 시리얼라이즈를 통해 전체 Entry를 얻는다.

그리곤 이 이름에 기반을 두고 경로-파일과 이름-인덱스 관계에 해당하는 폴더를 만든다.

리소스 이름의 폴더 경로를 얻고 저장된 인덱스에서 폴더를 찾은 뒤 그 폴더에 인덱스랑 파일 이름을 넣는다.      

  

        FPaths::GetPath(Filename); Get the path of the file
        FPaths::GetCleanFilename(Filename) Gets the name of the file including the suffix
        Filename = path + name = FPaths::GetPath(Filename) + FPaths::GetCleanFilename(Filename)    

 

경로-파일 이름-인덱스 구조로 폴더를 만드는 이유는 파일을 찾을 때 경로를 인덱스를 통해 해쉬해서 빨리 찾을 수 있고,
돌아온 값을 쪼개 폴더 경로와 파일 이름 얻고, 인덱스를 얻을 수 있다.

인덱스를 통해 TArray에 있는 리소스들의 위치를 얻어 낼 수 있다.

위 3단계를 모두 거쳤으면 FPakFile이 올바르게 생성됬다.

 

 

2. 패치 파일이면 우선 순위를 높임


패치 파일은 파일이 _숫자_P.pak 형태로 끝난다. 우선 순위는 100 + (숫자 * 100) 이당3. FPakPlatformFile에 FPakFile을 추가시키고 정렬한다. pak 파일이 마운트 될 때마다 FPakPlatformFile의 배열에 추가되고 내림차순으로 정렬된다.
높은 우선 순위의 파일을 먼저 읽는 이유가 이는데, 예를 들어 우선 순위가 제일 높은 패치 파일에서 어떤 리소스가 삭제됬다고 기록이 되있으면 더 낮은 우선 순위의 pak 파일에서 더이상 그 리소스를 찾지 않는다.

(제일 우선 순위가 높은 파일에서 읽으면 낮은 우선 순위 파일에선 그 리소스를 더 이상 찾지 않는다.)

 

FPakFile을 생성하고, 우선 순위를 정하고, 정렬하면 Mount 함수의 마운팅 과정이 끝나게 된다.

인터넷엔 Mount의 마운팅과 메모리에 로딩하는 것의 차이에 대한 질문들이 올라와있다.
위에서 본대로, Mount는 pak 파일의 정보 부분만 메모리에 로딩하는 것을 알 수 있다.
pak 파일의 정보엔 pak 파일에 몇 개의 파일들(asset package)를 저장하고 있는지, 파일들의 위치 등이 들어있다. 파일

정보를 읽기만 하지 실제로 파일을 로드하진 않는단 것이다 ;)

 

 

원문 : https://www.dazhuanlan.com/2019/09/26/5d8c840ed5ce9/

 

UE4资源加载(三)FPakPlatformFile相关 | 大专栏

 

www.dazhuanlan.com

원문 : zhuanlan.zhihu.com/p/54531649

 

UE4 Pak 文件格式

UE4 打包过程中,会调用 UnrealPak 将 Cook 后的文件资源打包成一整个 Pak 文件,这个 Pak 中的内容可以分为三大块,按写入顺序分别为: 文件内容区 + 文件索引信息区 + Pak文件信息区文件内容区: 依

zhuanlan.zhihu.com