UE4 热更新:HTTPChunkInstaller

 

热更大概有两种模式。
一、打一个基础包,更新包1是在基础包上叠加的,更新包2是在基础包和更新包1上叠加的,更新包2不包含更新包1的内容。新用户下载的时候需要下载更新包1,更新包2。
二、打一个基础包,更新包1是在基础包上叠加的,更新包2是在基础包上叠加的,更新包2包含更新包1的内容。新用户直接下载更新包2。

我看网上关于unreal的热更资料,基本上是以第一种的思路。我这里用的是第二种,使用unreal的HttpChunkInstall来热更。HttpChunkInstall里会把chunk的.pak分割成更小的文件.chunk文件。.mainfest文件里记录这些.chunk的guid。热更时获得本地和远程的.mainfest文件,比对里面这些.chunk的guid来判断,没有则下载,过期则删除,完成后组成.pak并挂载。

关于chunk和patch如果不太了解可以先看下官方文档再继续看下去。

https://docs.unrealengine.com/en-US/SharingAndReleasing/Patching/GeneralPatching/ChunkingExample/index.html

https://docs.unrealengine.com/en-US/SharingAndReleasing/Patching/GeneralPatching/CookingAndChunking/index.html

https://docs.unrealengine.com/en-US/SharingAndReleasing/Patching/GeneralPatching/HowToCreatePatch/index.html

 

使用:

启动HttpChunkInstall插件

在DefaultEngine.ini填写配置

[HTTPChunkInstall]
TitleFileSource=Http
CloudProtocol=http
CloudDomain=172.0.0.1:8081/Cloud/Android_ETC2
CloudDirectory=CloudDir

[HTTPOnlineTitleFile]
BaseUrl=172.0.0.1:8081/Cloud/Android_ETC2
EnumerateFilesUrl=CloudDir

[StreamingInstall]
DefaultProviderName=HTTPChunkInstaller

 

 

Build.cs里添加HTTPChunkInstaller模块,在自己的cpp里设置开启下载就会开始下载了。

​
    FHTTPChunkInstall* ChunkInstall = static_cast<FHTTPChunkInstall*>(FPlatformMisc::GetPlatformChunkInstall());
    if(ChunkInstall)
    {
        ChunkInstall->SetInstallSpeed(EChunkInstallSpeed::Fast);
    }

​

 

HTTPChunkInstall还有一个点是会优先按需加载。在设置里开启Should Acquire Missing Chunks on Load选项

当使用下列的方式加载资源时,如果该PrimaryAsset的chunk还没挂载,会调用到FHTTPChunkInstall::PrioritizeChunk添加进优先队列,在UpdatePendingInstallQueue里优先对PriorityQueue的chunk进行下载还挂载。

 

 

流程解释:

FHTTPChunkInstall的Tick函数就是怎么HttpChunkInstall的流程。

 

1ChunkInstallState::Setup和ChunkInstallState::SetupWait得到本地存储chunk的mainfest

 

2.ChunkInstallState::QueryRemoteManifests请求获得远程的master.mainfest数据,ChunkInstallState::SearchTitleFiles把每个chunk的mainfest数据存进TitleFilesToRead

 

3.然后ChunkInstallState::ReadTitleFiles请求获得chunk的mainfest数据,完成后调用ChunkInstallState::ReadComplete解析,TitleFilesToRead还有数据继续返回ChunkInstallState::ReadTitleFiles状态获取下一个数据,全部读取完成则Mount已有的并且不需要更新的pak。

ParseTitleFileManifest函数获取mainfest的内容,主要是把ChunkId加进ExpectedChunks里,并检测远程的chunk版本和InstalledManifests里查找到到chunk的版本是否一致,没有或不一致就加进RemoteManifests里。
ChunkMountTask里查找ContentPak的路径查找本地mainfest,判断chunkId是否在ExpectedChunks里,不在里面则继续找到pak并挂载。

 

4.ChunkInstallState::PostSetup是等待挂载完成后,当PriorityQueue.Num()为0是把更新状态设置成为Paused暂停下载,所以我们要开始下载才需要设置ChunkInstallSpeed状态。然后下一次转成Idle状态。

 

5.

优先加载PriorityQueue的chunk然后再加载前面ParseTitleFileManifest函数里添加进RemoteMainifests的chunk。

调用BeginChunkInstall进行下载,下载完成会调用OSSInstallComplete函数。

下面时OSSInstallComplete的部分截图:

ChunkCopyInstall是把BuildMainifest文件放进ManifestPath目录并删除HoldingMainifestPath目录,把bCopyDir为true时把下载到的ScrDir目录的内容移动到DestDir。然后查找 DestDir的pak并挂载。

 

6.等待ChunkCopyInstall完成,完成后表示该pak已经挂载完成,从RemoteManifests移除,然后调用EndInstall变成ChunkInstallState::Idle状态。

 

 

参考:

1.https://www2.slideshare.net/EpicGamesJapan/ue4-chunk-id

2.https://www.slideshare.net/EpicGamesJapan/ue4-95204920


版权声明:本文为u013507300原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。