用PakTools插件打包出来的pak文件,打包运行挂载pak文件后(使用PakLoader插件加载),有的pak文件系统无法加载指定路径的资产。
原因分析:#
使用cmd命令查看pak文件,得到如下输出:
1
2
3
4
5
6
|
cmd:UnrealPak.exe F:\00_Imrcao\01_MyProject\PreviewTools\Saved\DownloadedPaks\Models\chair_P.pak -List
Mount point ../../../PreviewTool/
LogPakFile: Display: "AssetRegistry.bin" offset: 0, size: 3948 bytes,
LogPakFile: Display: "Content/Assets/Materials/Models/Fabric_3.uasset"
LogPakFile: Display: "Content/Assets/Materials/Models/Fabric_3.uexp"
LogPakFile: Display: "Content/Assets/Materials/Models/Metal_2.uasset"
|
1
2
3
4
5
6
7
|
cmd:UnrealPak.exe F:\00_Imrcao\01_MyProject\PreviewTools\Saved\DownloadedPaks\Models\Bed_P.pak -List
Mount point ../../../
PreviewTool/Content/Assets/Texture/UMG/Thumbnails/Models/Bed.ubulk"
LogPakFile: Display: "PreviewTool/Content/Assets/Texture/UMG/Thumbnails/Models/Bed.uexp"
LogPakFile: Display: "PreviewTool/Content/Blueprints/Sku/Models/Bed.uasset"
LogPakFile: Display: "PreviewTool/Content/Blueprints/Sku/Models/Bed.uexp"
|
可以发现两个pak文件的mountPoint不一样,默认mountPoint系统自己计算,但也可以自己设置。那么mountPoint不一致会有什么问题呢?先看我的挂载代码。
1
|
UPakLoaderLibrary::MountPakFile(PakPaths, "")
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
//挂载pak
UPakLoaderLibrary::MountPakFile(PakPaths, "")
//注册挂载点,这个是核心
UPakLoaderLibrary::RegisterMountPoint("/PTPakDLC/", "../../../PreviewTool/Content/");
//
UPakLoaderLibrary::LoadPakAssetRegistryFile("../../../PreviewTool/AssetRegistry.bin");
//拼接资产名称
TArray<FString>pakFiles = UPakLoaderLibrary::GetFilesInPak(PakPaths, true);
for (auto pakFile : pakFiles)
{
FString str = UBlueprintPathsLibrary::GetExtension(pakFile);
if (!str.Equals("uexp") && !str.Equals("ubulk"))
{
//仅加载BPActor
if (pakFile.Contains("Blueprints/Sku"))
{
pakFile.Split("Content/", nullptr, &pakFile);
pakFile = "/PTPakDLC/" + pakFile;
//去掉.uasset后缀,获取纯包路径:/PTPakDLC/Blueprints/Sku/Lights/SpotLight_P
pakFile.Split(".", &pakFile, nullptr);
AssetFiles.AddUnique(pakFile);
}
}
}
//根据资产名称加载pak中的资产
UPakLoaderLibrary::GetPakFileClass(const FString &Filename)
|
问题在于最后需要的资产的路径:/PTPakDLC/Blueprints/Sku/Lights/SpotLight_P,需要长这样。但是我之前是这样拼接的:pakFile.Replace(TEXT(“PreviewTool/Content”), TEXT("/PTPakDLC/"));我以为所有的pak文件都像Bed_P.pak文件一样,内部资产路径都是以PreviewTool/Content开头的。但是chair_P.pak是以Content开头的。但实际上它们俩在引擎中的实际资产路径都是以../../../PreviewTool/Content开头,由于注册了挂载点:RegisterMountPoint("/PTPakDLC/", “../../../PreviewTool/Content/"),引擎就会把所有的”../../../PreviewTool/Content/“替换为”/PTPakDLC/",但又由于UPakLoaderLibrary::GetFilesInPak(PakPaths, true),返回的是PreviewTool/Content/…/…或者是Content/…/…。所以使用pakFile.Replace就不妥当,要想获取这样的路径:/PTPakDLC/Blueprints/Sku/…/…/,就必须改变方法,最终目的就是要让引擎能够识别/PTPakDLC/Blueprints/Sku/…/…/路径,并且在pak中确实有这个资产。
刚开始并不知道是这个原因导致的pak资产加载失败,尝试了很多方法,网上说加载了这个资产UPakLoaderLibrary::LoadPakAssetRegistryFile ("../../../PreviewTool/AssetRegistry.bin"),引擎可以自动识别资产路径,还没有深入测试。