简介

  • 通过 UnrealPak,可以将资源打包成 Pak 文件
  • Pak文件是UE4游戏生成的数据包文件。
    • Pak 之前一般先有 Cooked 步骤,将资源烘焙为对应平台支持的资源

      • 一般打包后的项目使用 Cooked 过的 pak
      • PIE 使用未 Cooked 过的 pak
    • Pak 一般放在游戏路径下的Content\Paks

    • 一个Pak 可以包含多个资源,可以是项目资源,也可以是非项目资源,如文本、视频等

    • 可用于热更新或DLC

    • 引擎自动加载 pak 的目录

      • [ProjectName]/Content/Paks
      • [ProjectName]/Saved/Paks
      • Engine/Content/Paks


UnrealPak

  • 命令行为一段,为方便阅读,故分行显示

支持参数(4.26)

UnrealPak <PakFilename> -Test
测试Pak文件能否打开(是否加密) UnrealPak <PakFilename> -Verify UnrealPak <PakFilename> -Info UnrealPak <PakFilename> -List [-ExcludeDeleted]
查看 UnrealPak <PakFilename> <GameUProjectName> <GameFolderName> -ExportDependencies=<OutputFileBase> -NoAssetRegistryCache -ForceDependsGathering UnrealPak <PakFilename> -Extract <ExtractDir> [-Filter=<filename>]
解包 UnrealPak <PakFilename> -Create=<ResponseFile> [Options]
打包 UnrealPak <PakFilename> -Dest=<MountPoint>
更改MountPoint UnrealPak <PakFilename> -Repack [-Output=Path] [-ExcludeDeleted] [Options] UnrealPak <PakFilename1> <PakFilename2> -diff
对比两个 pak UnrealPak <PakFolder> -AuditFiles [-OnlyDeleted] [-CSV=<filename>] [-order=<OrderingFile>] [-SortByOrdering] UnrealPak <PakFilename> -WhatsAtOffset [offset1] [offset2] [offset3] [...] UnrealPak <PakFolder> -GeneratePIXMappingFile -OutputPath=<Path> Options:
-blocksize=<BlockSize>
块大小 -bitwindow=<BitWindow> -compress
压缩 -order=<OrderingFile>
Cooker烘焙时的顺序文件 -diff (requires 2 filenames first)
比较 pak -enginedir (specify engine dir for when using ini encryption configs)
引擎目录 -projectdir (specify project dir for when using ini encryption configs)
项目目录 -encrypt
加密 -encryptindex (encrypt the pak file index, making it unusable in unrealpak without supplying the key)
加密索引,不提供key无法解密。可以在Project Setting -> Packaging - > Encrypt the pak index....配置 -encryptionini (specify ini base name to gather encryption settings from)
单独加密ini文件,可以在Project Setting -> Packaging - > Encrypt ini files inside pak files配置 -encryptionkeyoverrideguid (override the encryption key guid used for encrypting data in this pak file) -sign (generate a signature (.sig) file alongside the pak)
RSA签名:0x<私钥指数>+0x<私钥系数>+0x<公钥指数> 或者指定<KeyFileName> -aes
32位密钥 -extracttomountpoint (Extract to mount point path of pak file) -compressionformat[s]=<Format[,format2,...]> (set the format(s) to compress with, falling back on failures) -fallbackOrderForNonUassetFiles (if order is not specified for ubulk/uexp files, figure out implicit order based on the uasset order. Generally applies only to the cooker order) -moveBulkAndUptnlOrderLast (move all ubulk and uptnl files after all other resources in the first Order list. Ubulk and uptnl files will be at the end, and will preserve their order) 补充:
-abslog
指定打包日志文件路径 -UTF8Output
UTF8输出 -tempfiles=
烘焙文件临时存储 -multiprocess
多线程 patchpaddingalign=
数据块对齐 -generatepatch=
打Patch包时会添加的参数,后面指定要比较的Release文件 -cryptokeys=<Crypto.json>
指定 Crypto.json

设置环境变量

  • 为方便使用命令行,设置环境变量

  • UnrealPak.exe 是独立应用,也可以单独拷贝出来使用

  • 也可以使用 bat 文件。

Cook 文件打包 Pak

  • 注意 * 表示该文件夹下的所有目录
  • 默认调用方法
UnrealPak "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\Maps.pak" "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\*" -compress
  • 文本调用方法

    • 设置ResponseFile

      • 第一个路径为 Cook 后的资源路径
      • 第二个路径为 挂载路径
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\NewMap.uexp" "../../../DesignPatterns/Content/Maps/NewMap.uexp" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\NewMap.umap" "../../../DesignPatterns/Content/Maps/NewMap.umap" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\NewMap_BuiltData.uasset" "../../../DesignPatterns/Content/Maps/NewMap_BuiltData.uasset" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\NewMap_BuiltData.ubulk" "../../../DesignPatterns/Content/Maps/NewMap_BuiltData.ubulk" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\NewMap_BuiltData.uexp" "../../../DesignPatterns/Content/Maps/NewMap_BuiltData.uexp" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\LightMap\LightMap.uexp" "../../../DesignPatterns/Content/Maps/LightMap/LightMap.uexp" -compress
      "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Content\Maps\LightMap\LightMap.umap" "../../../DesignPatterns/Content/Maps/LightMap/LightMap.umap" -compress
    • 执行脚本

      UnrealPak "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\Maps.pak" -create="C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\MyPakLisk.txt"
    • bat 文件

      @ECHO OFF
      ECHO ------------------------------------------------------------------
      ECHO UnrealPak Strart Create Pak
      ECHO ------------------------------------------------------------------ set PakFilename="C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\Maps.pak"
      set ResponseFile="C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\MyPakLisk.txt"
      set UnrealPak="C:\SoftwareInstallation\EpicGames\UE_4.26\Engine\Binaries\Win64\UnrealPak.exe"
      CALL %UnrealPak% %PakFilename% -create=%ResponseFile% ECHO ------------------------------------------------------------------
      ECHO Finished
      ECHO ------------------------------------------------------------------
      PAUSE
  • 加密pak

    unrealpak PAK_NAME.pak -create=ResponseFile -compress -encrypt -encryptindex -aes=32bit_AESKey
    
    // 在\Config\DefaultEncryption.ini文件中查找AES的密钥,4.26 提示用 -cryptokeys
    -encryptindex -encryptionini -enginedir="<EngineDir>" -projectdir="<GameDir>" -platform=Windows // 新版使用,可将项目设置中的 Encryption Key 填入到json中
    //json 格式为 { "EncryptionKey": {"Key": "tmAjE6/depliVQgG3XgI60bwrQE2iGgg5n8VRPXrGm0="} }
    -encrypt -encryptindex -compress -cryptokeys=<Crypto.json>
  • 项目打包截取的部分日志

    • 可以在项目设置中设置签名与加密
    Output from:
    "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\DesignPatterns.uproject"
    "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\StagedBuilds\WindowsNoEditor\DesignPatterns\Content\Paks\DesignPatterns-WindowsNoEditor.pak"
    -create="C:\Users\Alice\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+SoftwareInstallation+EpicGames+UE_4.26\PakList_DesignPatterns-WindowsNoEditor.txt"
    -cryptokeys="C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Saved\Cooked\WindowsNoEditor\DesignPatterns\Metadata\Crypto.json"
    -order="C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\Build\WindowsNoEditor\FileOpenOrder\CookerOpenOrder.log"
    -encryptindex
    -patchpaddingalign=2048
    -platform=Windows
    -multiprocess
    -abslog="C:\Users\Alice\AppData\Roaming\Unreal Engine\AutomationTool\Logs\C+SoftwareInstallation+EpicGames+UE_4.26\UnrealPak-DesignPatterns-WindowsNoEditor-2021.05.22-17.58.51.txt"

解包 Pak

  • 解普通 pak

    UnrealPak "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\MyPaks\Maps.pak" -Extract "C:\Users\Alice\Documents\Unreal Projects\DesignPatterns\ExtractPak"
  • 解加密 pak

    unrealpak <PakFilename> -Extract <ExtractDir> -aes=32bit_AESKey
    
    unrealpak <PakFilename> -Extract <ExtractDir> -cryptokeys="[ProjectName]\Saved\Cooked\WindowsNoEditor\[ProjectName]\Metadata\Crypto.json"
    
    unrealpak <PakFilename> -Extract -encryptindex -encryptionini -enginedir="<EngineDir>" -projectdir="<GameDir>" -platform=Windows

查看Pak

  • -Test

  • -Verify

  • -Info

  • -List [-ExcludeDeleted]

  • 必要时需要加上密钥签名


Pak 文件的挂载与加载

挂载与加载的区别

  • 挂载(Mount)

    • 告诉系统可以从哪些路径访问Pak文件包含的文件,起到提供路径的作用
    • 挂载pak文件之后,可以通过常规的方式来访问其中的文件
    • FPlatformFileManager
    • PakPlatformFile
      • 可以挂载多个Pak文件,其内部有一个记录FPakFile的List
  • 加载(Load)
    • 一般指把文件的内容加载到内存中了

简单使用-测试资源准备

  • 简单实现用UI切换材质的gong

  • ToPak 为要打包的资源,不建议和挂载点路径 不一致,容易导致依赖丢失

    ToPak
    ├─ BP_PakTest1.uasset
    ├─ UMG_Test.uasset
    ├─ Material
    │ ├─ M_Pak.uasset
    │ ├─ M_Pak_Inst.uasset
    │ └─ M_Pak_Inst1.uasset
    └─ Texture
    ├─ BlueHPTex.uasset
    ├─ GreyHPTex.uasset
    └─ RedHPTex.uasset
  • BP_PakTest1

  • UMG_Test

  • UnrealPak打包

指定挂载

  • .Build.cs 添加 PakFile 模块

  • 主要代码

    TSharedPtr<FPakPlatformFile> PakPlatformFile;
    
    	IPlatformFile* InnerPlatformFile;
    
    	UFUNCTION(BlueprintCallable)
    bool LoadPak(const FString& PakPath);
    void ALoadPakActor::BeginPlay()
    {
    Super::BeginPlay(); //获取当前使用的平台
    InnerPlatformFile = &FPlatformFileManager::Get().GetPlatformFile();
    UE_LOG(LogTemp, Warning, TEXT("InnerPlatformFile: %s"), InnerPlatformFile->GetName()); //初始化PakPlatformFile
    PakPlatformFile = MakeShareable(new FPakPlatformFile());
    PakPlatformFile.Get()->Initialize(InnerPlatformFile, TEXT(""));
    } bool ALoadPakActor::LoadPak(const FString& PakPath)
    {
    bool Result = false; // 切换到 pak平台
    FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile.Get()); // 获取pak文件
    TSharedPtr<FPakFile> PakFile = MakeShareable(new FPakFile(InnerPlatformFile, *PakPath, false));
    FString MountPoint = PakFile->GetMountPoint();
    UE_LOG(LogTemp, Warning, TEXT("Default Mount Point: %s"), *MountPoint); #if WITH_EDITOR
    // PIE模式下,MountPoint 使用绝对路径
    // 打包模式下,MountPoint 使用相对路径
    MountPoint = FPaths::ConvertRelativePathToFull(MountPoint);
    UE_LOG(LogTemp, Warning, TEXT("Default Mount Point Full Path: %s"), *MountPoint); // 设置pak文件的Mount点,因为在制作pak的时候已在文本中设定 mount point,故省略此步骤
    MountPoint = FPaths::ProjectContentDir() + TEXT("DLC/"); // 可在此处检测 默认MountPoint的绝对路径释放和本条语句执行结果是否一致
    MountPoint = FPaths::ConvertRelativePathToFull(MountPoint); PakFile->SetMountPoint(*MountPoint);
    UE_LOG(LogTemp, Warning, TEXT("New Mount Point Full Path: %s"), *MountPoint);
    #endif // 对pak文件进行挂载
    if (PakPlatformFile->Mount(*PakPath, 1, *MountPoint))
    {
    // 加载 pak 里的资源
    UClass* BP_PakTestClass = LoadClass<AActor>(nullptr, TEXT("Blueprint'/Game/DLC/BP_PakTest1.BP_PakTest1_C'"));
    if (BP_PakTestClass)
    {
    GetWorld()->SpawnActor<AActor>(BP_PakTestClass, FVector::ZeroVector, FRotator::ZeroRotator);
    Result = true;
    }
    else
    UE_LOG(LogTemp, Error, TEXT("Load BP_PakTest1 Class Failed")); // 遍历 pak 里的资源
    TArray<FString> AssetList;
    PakFile->FindPrunedFilesAtPath(AssetList, *PakFile->GetMountPoint(), true, false, true);
    for (FString itemPath : AssetList)
    {
    UE_LOG(LogTemp, Warning, TEXT("%-30s\t%s"), *FPackageName::GetShortName(itemPath), *itemPath);
    // 此处可异步加载资源
    }
    }
    else
    UE_LOG(LogTemp, Error, TEXT("Mount Pak Failed")); // 设置回原来的PlatformFile, UE4.26
    // 不加该条语句,本测试崩溃,报错:Pure Virtual function being called while application was running
    FPlatformFileManager::Get().SetPlatformFile(*InnerPlatformFile); return Result;
    }

注意

  • 如果可以挂起,但无法加载,可以测试相对路径与绝对路径的问题

    • PIE模式下,MountPoint 使用绝对路径
    • 打包模式下,MountPoint 使用相对路径
  • pak 文件右键属性赋值的路径,有时会导致挂载失败(无缘无故的bug调了一下午,烦躁)
  • PakPlatformFile->Unmount() 可卸载
  • PakPlatformFile->GetMountedPakFilenames() 获取已加载的pak,可用于检测,避免重复加载

使用 FCoreDelegates 挂载

  • 默认使用 Pak里的Mount Point

  • 测试时,PIE模式下挂载成功,但是loadClass 失败,应该是路径的问题.打包后没问题

  • 修改 部分代码

    bool ALoadPakActor::LoadPak(const FString& PakPath)
    {
    bool Result = false;
    if (FCoreDelegates::OnMountPak.IsBound())
    {
    if (FCoreDelegates::OnMountPak.Execute(PakPath, 0, nullptr))
    {
    UClass* BP_PakTestClass = LoadClass<AActor>(nullptr, TEXT("Blueprint'/Game/DLC/BP_PakTest1.BP_PakTest1_C'"));
    if (BP_PakTestClass)
    {
    GetWorld()->SpawnActor<AActor>(BP_PakTestClass, FVector::ZeroVector, FRotator::ZeroRotator);
    Result = true;
    }
    else
    UE_LOG(LogTemp, Error, TEXT("Load BP_PakTest1 Class Failed")); }
    else
    UE_LOG(LogTemp, Error, TEXT("OnMountPak.Execute() Failed"));
    }
    else
    UE_LOG(LogTemp, Error, TEXT("OnMountPak.IsBound() Failed")); return Result;
    }

修复

修复引用

  • 最开始资源是存放在 ToPak 目录下,但是挂载在 DLC 目录下 ,因而容易造成引用混乱
  • 确保 pak 里的其他资源加载,本问省略了该步骤
  • 因为使用一个工程进行测试,现在将资源 转移到 DLC 下打包pak,使用时,将源资源移动到或者删除。
  • 这样 BP_PakTest1 和 UMG_Test 可以保持引用

材质丢失

  • 由于Pak 并没有包含 Shader,从而导致依赖丢失

  • 解决方法1:ProjectSetting → Packaging → Share Material Shader Code 关闭共享,但这样会使 Shader 变多

  • 解决方法2:将母材质至于项目内,使用 Material Instanse 打包进 pak, PIE 下也可以生效

    • FShaderLibraryInstance、FRHIShaderLibrary、openlibrary、shaderbytecode

挂载加密pak

  • 默认 打包 cook 会生成 Crypto.json,路径为 [ProjectName]\Saved\Cooked\WindowsNoEditor\[ProjectName]\Metadata\Crypto.json

  • 自定义最简 Crypto.json

    {
    "EncryptionKey": {"Key": "tmAjE6/depliVQgG3XgI60bwrQE2iGgg5n8VRPXrGm0="}
    }
  • 打包 pak

    UnrealPak "C:\Users\Alice\Documents\Unreal Projects\tips\MyPak\PakTest.pak"
    -create="C:\Users\Alice\Documents\Unreal Projects\tips\MyPak\PakList.txt"
    -encryptindex
    -compress
    -cryptokeys="C:\Users\Alice\Documents\Unreal Projects\tips\Config\Crypto.json"
  • 修改代码

    // 在挂载前使用,本文调用位置为 ALoadPakActor::LoadPak() 首出
    // 绑定PAK解密函数
    FCoreDelegates::GetPakEncryptionKeyDelegate().BindUObject(this, &ALoadPakActor::InitEncrypt); //解密函数,Base64转换
    void ALoadPakActor::InitEncrypt(uint8* Key) {
    FString KeyStr = TEXT("tmAjE6/depliVQgG3XgI60bwrQE2iGgg5n8VRPXrGm0=");
    TArray<uint8> KeyBase64Ary;
    FBase64::Decode(KeyStr, KeyBase64Ary);
    char* KeyU8 = TCHAR_TO_UTF8(*KeyStr);
    FMemory::Memcpy(Key, KeyBase64Ary.GetData(), FAES::FAESKey::KeySize);
    }

扩展工具


参考

【UE4 C++】 UnrealPak 与 Pak 的制作、挂载、加载的更多相关文章

  1. 用css3制作旋转加载动画的几种方法

    以WebKit为核心的浏览器,例如Safari和Chrome,对html5有着很好的支持,在移动平台中这两个浏览器对应的就是IOS和Android.最近在开发一个移动平台的web app,那么就有机会 ...

  2. [前端随笔][CSS] 制作一个加载动画 即帖即用

    说在前面 描述 [加载中loading...] 的动画图片往往使用GIF来实现,但GIF消耗资源较大,所以使用CSS直接制作更优. 效果传送门1 效果传送门2 关键代码 @keyframes 规则 用 ...

  3. [Swift通天遁地]一、超级工具-(11)使用EZLoadingActivity制作Loading加载等待动画

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. 如何制作快速加载的HTML页面

    整理出来的tip 减小页面的大小 在页面下载中,页面的大小至今扮演着非常重要的因素. 减小页面的大小能够通过排除不必要空格,注释,动态内嵌脚本,和放入外部文件的 CSS 等在页面结构中很小的改变都能够 ...

  5. css3动画特效:纯css3制作win8加载动画特效

    Windows 8     完整效果如上图:这个里面可能是css冲突,喜欢的可以自己去体征一下:   css特效代码: <style type="text/css"> ...

  6. CSS3——制作正在加载页面loading...

    今天做了好多小东西,还挺开心的~ <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  7. Unity跳转场景进度条制作教程(异步加载)

    Unity跳转场景进度条制作 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享 ...

  8. ue4 plugin的编译加载

    插件Plugin: 本来应该是指一种纯以接口与外界打交道的程序模块,在同一接口背后可以有多种实现,更换实现完全不影响客户端代码(不用重编). 但是在ue4的世界里,插件似乎不是这个意思,仅仅是一种可以 ...

  9. UE4 异步资源加载

    http://blog.csdn.net/pizi0475/article/details/48178861 http://blog.sina.com.cn/s/blog_710ea1400102vl ...

随机推荐

  1. 【Python机器学习实战】决策树与集成学习(五)——集成学习(3)GBDT应用实例

    前面对GBDT的算法原理进行了描述,通过前文了解到GBDT是以回归树为基分类器的集成学习模型,既可以做分类,也可以做回归,由于GBDT设计很多CART决策树相关内容,就暂不对其算法流程进行实现,本节就 ...

  2. NOIP模拟21:「Median·Game·Park」

    T1:Median   线性筛+桶+随机化(??什么鬼?).   首先,题解一句话秀到了我: 考虑输入如此诡异,其实可以看作随机数据   随机数据??   这就意味着分布均匀..   又考虑到w< ...

  3. 比培训机构还详细的 Python 学习路线,你信吗 0^0

    前言 这其实是将自己写的文章进行一个总结分类,并不代表最佳学习路线 会不断更新这篇文章...没链接的文章正在编写ing...会不会哪天我的这个目录就出现在培训机构的目录上了... 目前实战比较少(要是 ...

  4. Jenkins(5)- 新建一个job并快速体验完整流程

    如果想从头学起Jenkins的话,可以看看这一系列的文章哦 https://www.cnblogs.com/poloyy/category/1645399.html 新建一个任务(job) 输入job ...

  5. 用Java写了一个程序,将一个Mysql库中的表,迁移到另外一个server上的Mysql库中

    用Navicat做数据迁移,因为数据量比较大,迁移过过程中一个是进展不直观,另外就是cpu占用率高的时候,屏幕跟死机了一样点不动按钮,不好中断. 想了想,干脆自己写一个. 在网上找了一个sqllite ...

  6. eclipse中的一些快捷键

    1.内容提示 Alt+/ 2.快速修复 ctrl+/ 3.导包 ctrl+shift+o 4.格式代码块 ctrl+shift+o 5.向前向后 Alt+方向键 6.添加注释 ctrl+shift+/ ...

  7. PHP中命名空间是怎样的存在?(三)

    这是与命名空间有关的最后一篇.最后还是两个比较简单的内容,是关于命名空间和全局相关的一些类.函数.常量的使用对比.当然,最后我们还会总结一下命名空间的名称解析规则做为这三篇系列文章的结束. 全局空间 ...

  8. CSS linear-gradient() 函数

    用于背景颜色渐变或画线条等场景 linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片. 创建一个线性渐变,需要指定两种颜色,还可以实现不同方向(指定为一个角度)的渐变效 ...

  9. Apache设置禁止访问网站目录

    使用Apache作为Web服务器的时候,在当前目录下没有index.html|php等入口就会显示目录.让目录暴露在外面是非常危险的事. 找到Apache的配置文件 /etc/apache2/apac ...

  10. centos7.6,nginx1.18,php-7.4.6,mysql-5.7.30 安装

    #1.下载,来自各官网 nginx-1.18.0.tar.gz php-7.4.6.tar.gz mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz #下载到本地再传 ...