写的有点乱。。。。。

这里有一些可供参考的文档:

UE4 Pak 相关知识总结 https://arcecho.github.io/2017/07/02/UE4-Pak-%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/

UnrealPak的使用笔记  https://blog.ch-wind.com/unrealpak-note/

UE4补丁与DLC  https://blog.ch-wind.com/ue4-patch-release-dlc/

 

pak文件是游戏中的资源打包后生成的文件。

对游戏的更新,如果只是资源更新,而没有c++的更新,可通过只更新pak文件进行

生成更新用的pak,通常我们是通过基础release版本,来生成patch(补丁),可通过项目启动程序的配置启动描述文件来生成。生成更新pak的方法如下:

http://api.unrealengine.com/CHN/Engine/Deployment/Patching/index.html

 

 

在打包时,如果指定生成release版本2.0。在没有指定生成补丁时,会在release 2.0目录中的对应版本目录2.0下生成一个包含所有资源文件pak文件。

 

如果生成release版本2.0指定了基于1.0生产补丁。则会在指定的基础版本1.0的目录中,生成一个_p.pak结尾的补丁包,而对应的版本2.0目录下没有任何pak文件。

如果接下来生成release版本3.0时仍然指定了基于2.0生产补丁。则会在2.0 生成一个包含全部资源的_p.pak结尾的补丁包。3.0目录下没有pak。

如果接下来生成release版本4.0时仍然指定了基于3.0生产补丁。则会在3.0 生成一个包含全部资源的_p.pak结尾的补丁包。4.0目录下没有pak。

 

如果按上面生成release版本的同时生成补丁的方法进行补丁更新。补丁包会越来越大。且相当于全部替换。

所以一般在生成release版本时,不应该同时指定生成补丁包。

生成补丁包应该单独生成。

 

通常我们在生成下一个版本时。我们设置两个启动描述文件。

一个用于生成版本。

一个用于生成基于上一个版本的补丁。

ue4 版本资源更新

 

在生成版本的描述文件中。我们这样设置:

在生成补丁的描述文件中。我们这样设置

ue4 版本资源更新

ue4 版本资源更新

我们在F:\package\2.0 depend 1.0\WindowsNoEditor\PakAndDLC\Content\Paks 文件夹中,可以找到 补丁文件: 【项目名称】-【目标平台】_0_P.pak 

这就是我们需要的。我们可以将它改成 [项目名称]_1.0_2.0_P.pak

 

 

对pak文件的挂载的优先级决定了,搜索资源的顺序。

当我们更新了资源后,需要让我们搜索资源时优先搜索新的pak文件。

挂载pak是在FPakPlatformFile::Mount 函数中, 当挂载时,我们同时指定了pak的优先级。

 

 

然后我们就可以把我们这个1.0版本的Saved/Paks/ 目录下, 然后就可以使用了

之后我们还可以生成[项目名称]_2.0_3.0_P.pak. 同样放在Saved/Paks/ 目录下。

因为FPakPlatformFile::Mount 函数中 对 以_数字_p.pak结尾的 pak文件挂载优先级的特殊处理关系。 

[项目名称]_2.0_3.0_P.pak 优先级最高, 之后是[项目名称]_1.0_2.0_P.pak, 再之后才是【项目名称】-【目标平台】.pak 

 

在实际适用中,我们可以根据版本顺序。从http服务器上依次下载从当前客户端版本到最新版本的pak补丁。

然后根据版本顺序,设置FPakPlatformFile::Mount中的挂载优先级。为了使用方便。如果我们的版本补丁是链式的(也就是1.0-2.0 2.0-3.0, 而不是 1.0-3.0 中间跨越了几个版本)。我们可以用【项目名称】_整数版本号_P.pak为版本名称。

 

 

如果我们需要使用蓝图的移动补丁工具节点来安装我们的补丁的话。我们可以使用UE4中的BuildPatchTool.exe 来生成需要的manifest文件和 CloudDir。移动补丁工具节点

 

该工具是在Engine\Binaries\Win64 文件夹中。

BuildPatchTool.exe -mode=PatchGeneration -BuildRoot=F:\test -CloudDir=F:\CloudDir -AppName="appName" -AppLaunch="" -AppArgs="" -BuildVersion="1.0"

 

通常我们只需要指定-BuildRoot和-CloudDir。BuildRoot 代表了存放pak的文件夹。CloudDir代表了生成的文件存放的位置。

其他参数不能省略。 APPName和BuildVersion 将生成manifest文件的名称。这里就是appName1.0.manifest。

 

 

将补丁复制到Saved/Paks/文件夹中可以在c++中导出下面两个函数

#include "GenericPlatform/GenericPlatformFile.h"

bool UMyBlueprintFunctionLibrary::copyfile(const FString To, const FString From)

{

       return IPlatformFile::GetPlatformPhysical().CopyFile(*To, *From);

}

bool UMyBlueprintFunctionLibrary::CreateDirectoryTree(const FString directory)

{

       return IPlatformFile::GetPlatformPhysical().CreateDirectoryTree(*directory);

}

 

 

 

ue4 版本资源更新

 

将补丁 pak 文件放入设备上 FPakPlatformFile::GetPakFolders 所设置的任何 pak 搜索目录后,它将自动装载

pak 搜索目录:

          OutPakFolders.Add(FString::Printf(TEXT("%sPaks/"), *FPaths::ProjectContentDir()));

       OutPakFolders.Add(FString::Printf(TEXT("%sPaks/"), *FPaths::ProjectSavedDir()));

       OutPakFolders.Add(FString::Printf(TEXT("%sPaks/"), *FPaths::EngineContentDir()));

 

也就是 工程的 工程名/Content/Paks/ 目录, 工程名/Saved/Paks/ 目录,和 Engine/Content/Paks/ 目录

这三个目录中的pak文件将在游戏启动时自动加载!! 我们可以把下载过来的需要自动加载的pak放在工程名/Saved/Paks/ 中。

为了确定各补丁的优先顺序,装载系统使用文件名末尾的 _p 来确定其优先于其他 pak 文件。您可将补丁 pak 文件重命名,但必须 在文件名末尾包括 _p.pak

 

FPakPlatformFile::Mount 函数的参数

bool FPakPlatformFile::Mount(const TCHAR* InPakFilename, uint32 PakOrder, const TCHAR* InPath /*= NULL*/)

inPakFileName:是加载的pak的文件路径。

PakOrder:是加载的优先级, 数值越大优先级越高。

对于以_P.pak为结尾的文件:

如果是以_[数字]_P.pak为结尾(比如_1_P.pak),PakOrder=PakOrder +100*(数字取整+1),

如果不是以_[数字]_P.pak为结尾PakOrder=PakOrder+100

inPath 是挂载的路径。通常设为NULL。代表/Game

 

 

FPakPlatformFile::Initialize 会加载FPakPlatformFile::GetPakFolders返回的文件夹中的所有的还未加载过的PAK文件。

这时候PAK挂载的路径inPath 都是NULL

PakOrder 通过 FPakPlatformFile::GetPakOrderFromPakFilePath 获得

 

int32 FPakPlatformFile::GetPakOrderFromPakFilePath(const FString& PakFilePath)

{

       if (PakFilePath.StartsWith(FString::Printf(TEXT("%sPaks/%s-"),  *FPaths::ProjectContentDir(), FApp::GetProjectName())))

       {

              return 4;

       }

       else if (PakFilePath.StartsWith(FPaths::ProjectContentDir()))

       {

              return 3;

       }

       else if (PakFilePath.StartsWith(FPaths::EngineContentDir()))

       {

              return 2;

       }

       else if (PakFilePath.StartsWith(FPaths::ProjectSavedDir()))

       {

              return 1;

       }

       return 0;

}

 

 

首先存在于工程名/Content/Paks/ 中的以工程名加-开头的pak文件的pakOrder 返回4

其他存在于工程名/Content/Paks/ 中的pak文件的pakOrder 返回3

存在于Engine/Content/Paks/ 中的pak文件的pakOrder 返回2

存在于工程名/Saved/Paks/ 中的pak文件的pakOrder 返回1

其他返回0

 

 

相关文章: