首页 置换 选车 估价 问答 生活 经销商 车管所 汽车资讯 汽车销量 车牌查询 今日油价 天气预报
您的位置: 首页 > 生活 > 其他 > ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)
ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)
更新时间:2024-06-30 04:46:07

UE4官网针对热更新有较为详细的步骤,但是其中漏掉的几个问题导致实现不了效果。

总的来说可以分为四大步。

第一步:自己的项目设置好插件ChunkDownloader

1.新建第三人称c 项目工程,设置分块打包

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)1

2.勾选插件ChunkDownloader

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)2

3.修改项目的 Build.cs 文件

PrivateDependencyModuleNames.AddRange(

new string[] { "ChunkDownloader" }

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)3

4.保存后重新生成项目文件。操作:右键点击你的 .uproject 文件,然后点击 生成项目文件(Generate Project Files)

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)4

第二步:资源分块,然后打包。为了测试方便,新建三个map,分别放在不同的文件夹。我的是Test,Test2,Test3.

  1. 添加资源分块标签。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)5

标签设置如图:红框内需必备

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)6

属性解释:

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)7

依次对自己的测试资源添加标签。

2.打包默认设置即可。这样你可以在打出的包里看到分好的pak文件。红框ID与你的标签ID对应。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)8

第三步:构建资源清单与托管本地测试服务器

1.构建资源清单。这里注意,英文字符下 TAB建进行属性空格。

我的清单如下:

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)9

资源文件夹结构,其中Windows文件夹中放的是分块后的pak文件

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)10

稍作解释:

第1行是需要下载更新的pak数目

第2行理解为资源和清单所在的文件夹

后面的几行就是pak资源相关的。共5个属性。资源名字,资源大小(右键资源看其属性字节数),版本号,ChunkID,资源所在位置。

2.文件托管到本地测试服务器

如何创建本地测试服务器这里不啰嗦,可以参考ue4官网。

但是这里要注意:新建文件夹PatchingDemoCDN,除了上传我们前面准备好的资源和清单即PatchingDemoKey文件夹。我们还需要在PatchingDemoCDN文件夹中新建表单

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)11

这个表单中我们要写上$BUILD_ID对应的也就是资源和清单所在的文件夹PatchingDemoKey

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)12

最后我们还需要在项目的配置表DefaultGame.ini中添加用来下载资源的网站地址。这里我们是用本地服务器测试的。

[/Script/Plugins.ChunkDownloader PatchingDemoLive]

CdnBaseUrls=127.0.0.1/PatchingDemoCDN

第三步:编辑代码和逻辑。(开始不必扩展,实现基本功能即可)

1.GameInstance不仅具有可以绑定的相应初始化和关闭函数,而且还可以在游戏运行时持续访问ChunkDownloader。

所以使用 GameInstance 作为基类创建 新C 类。将其命名为 PatchingDemoGameInstance

最后代码为:

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

#include "Engine/GameInstance.h"

#include "PatchingDemoGameInstance.generated.h"

/**

*

*/

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPatchCompleteDelegate, bool, Succeeded);

UCLASS()

class UPatchingDemoGameInstance : public UGameInstance

{

GENERATED_BODY()

public:

/** Overrides */

virtual void Init() override;

virtual void Shutdown() override;

/** Delegates */

/** Fired when the patching process succeeds or fails */

UPROPERTY(BlueprintAssignable, Category = "Patching")

FPatchCompleteDelegate OnPatchComplete;

/** Starts the game patching process. Returns false if the patching manifest is not up to date. */

UFUNCTION(BlueprintCallable, Category = "Patching")

bool PatchGame();

UFUNCTION(BlueprintPure, Category = "Patching|Stats")

void GetLoadingProgress(int32& FilesDownloaded, int32& TotalFilesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const;

protected:

//Tracks Whether or not our local manifest file is up to date with the one hosted on our website

bool bIsDownloadManifestUpToDate;

void OnManifestUpdateComplete(bool bSuccess);

/** List of Chunk IDs to try and download */

UPROPERTY(EditDefaultsOnly, Category = "Patching")

TArray<int32> ChunkDownloadList;

/** Called when the chunk download process finishes */

void OnDownloadComplete(bool bSuccess);

/** Called whenever ChunkDownloader's loading mode is finished*/

void OnLoadingModeComplete(bool bSuccess);

/** Called when ChunkDownloader finishes mounting chunks */

void OnMountComplete(bool bSuccess);

};

.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "PatchingDemoGameInstance.h"

#include "ChunkDownloader.h"

#include "Misc/CoreDelegates.h"

#include "AssetRegistryModule.h"

void UPatchingDemoGameInstance::Init()

{

Super::Init();

const FString DeploymentName = "PatchingDemoLive";

const FString ContentBuildId = "PatchingDemoKey";

// initialize the chunk downloader

TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetOrCreate();

// TODO 安卓下载方式

// Downloader->Initialize("Android", 8);

Downloader->Initialize("Windows", 8);

// load the cached build ID

Downloader->LoadCachedBuild(DeploymentName);

// update the build manifest file

TFunction<void(bool bSuccess)> UpdateCompleteCallback = [&](bool bSuccess){bIsDownloadManifestUpToDate = true;};

Downloader->UpdateBuild(DeploymentName, ContentBuildId, UpdateCompleteCallback);

}

void UPatchingDemoGameInstance::Shutdown()

{

Super::Shutdown();

// Shut down ChunkDownloader

FChunkDownloader::Shutdown();

}

void UPatchingDemoGameInstance::OnManifestUpdateComplete(bool bSuccess)

{

bIsDownloadManifestUpToDate = bSuccess;

}

void UPatchingDemoGameInstance::GetLoadingProgress(int32& BytesDownloaded, int32& TotalBytesToDownload, float& DownloadPercent, int32& ChunksMounted, int32& TotalChunksToMount, float& MountPercent) const

{

//Get a reference to ChunkDownloader

TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();

//Get the loading stats struct

FChunkDownloader::FStats LoadingStats = Downloader->GetLoadingStats();

//Get the bytes downloaded and bytes to download

BytesDownloaded = LoadingStats.BytesDownloaded;

TotalBytesToDownload = LoadingStats.TotalBytesToDownload;

//Get the number of chunks mounted and chunks to download

ChunksMounted = LoadingStats.ChunksMounted;

TotalChunksToMount = LoadingStats.TotalChunksToMount;

//Calculate the download and mount percent using the above stats

DownloadPercent = ((float)BytesDownloaded / (float)TotalBytesToDownload)*100.0f;

MountPercent = ((float)ChunksMounted / (float)TotalChunksToMount)*100.0f;

}

void UPatchingDemoGameInstance::OnLoadingModeComplete(bool bSuccess)

{

OnDownloadComplete(bSuccess);

}

void UPatchingDemoGameInstance::OnMountComplete(bool bSuccess)

{

OnPatchComplete.Broadcast(bSuccess);

}

bool UPatchingDemoGameInstance::PatchGame()

{

// make sure the download manifest is up to date

if (bIsDownloadManifestUpToDate)

{

// get the chunk downloader

TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();

// report current chunk status

for (int32 ChunkID : ChunkDownloadList)

{

int32 ChunkStatus = static_cast<int32>(Downloader->GetChunkStatus(ChunkID));

UE_LOG(LogTemp, Display, TEXT("Chunk %i status: %i"), ChunkID, ChunkStatus);

}

TFunction<void(bool bSuccess)> DownloadCompleteCallback = [&](bool bSuccess) {OnDownloadComplete(bSuccess); };

Downloader->DownloadChunks(ChunkDownloadList, DownloadCompleteCallback, 1);

// start loading mode

TFunction<void(bool bSuccess)> LoadingModeCompleteCallback = [&](bool bSuccess) {OnLoadingModeComplete(bSuccess); };

Downloader->BeginLoadingMode(LoadingModeCompleteCallback);

return true;

}

// we couldn't contact the server to validate our manifest, so we can't patch

UE_LOG(LogTemp, Display, TEXT("Manifest Update Failed. Can't patch the game"));

return false;

}

void UPatchingDemoGameInstance::OnDownloadComplete(bool bSuccess)

{

if (bSuccess)

{

UE_LOG(LogTemp, Display, TEXT("Download complete"));

// get the chunk downloader

TSharedRef<FChunkDownloader> Downloader = FChunkDownloader::GetChecked();

FJsonSerializableArrayInt DownloadedChunks;

for (int32 ChunkID : ChunkDownloadList)

{

DownloadedChunks.Add(ChunkID);

}

//Mount the chunks

TFunction<void(bool bSuccess)> MountCompleteCallback = [&](bool bSuccess) {OnMountComplete(bSuccess); };

Downloader->MountChunks(DownloadedChunks, MountCompleteCallback);

OnPatchComplete.Broadcast(true);

}

else

{

UE_LOG(LogTemp, Display, TEXT("Load process failed"));

// call the delegate

OnPatchComplete.Broadcast(false);

}

}

2.使用 PatchingDemoGameInstance 作为基类创建 新蓝图,命名为 CDGameInstance

3.打开CDGameInstance,添加chunk列表

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)13

4.创建名为 PatchingGameMode 的新游戏模式 蓝图

5.项目做如下设置。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)14

6.第三人称游戏map设置gamemode为PatchingGameMode

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)15

7.打开PatchingGameMode,添加如下蓝图逻辑。

beginPlay后添加:patchGame返回值为true则进入tick即开始下载资源。否则根据资源数进行进一步检测。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)16

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)17

tick后添加:大概意思就是资源下载并且装载完打开Test3地图。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)18

到此代码,逻辑都写好了。

第四步:打包测试

1.直接打包。

结果是包文件夹里的Content中的paks文件夹有四个pak文件。删掉ID为1001-1003的pak。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)19

2.运行.exe

结果如下:

下载中

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)20

下载完成,3秒后进入Test3地图。

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)21

下载的文件:

ue4组件编程(UE4热更新之ChunkDownloaderPlugin使用)22

,
上一篇:桂花树怎么修剪 下一篇:无耻的意思
相关推荐RECOMMEND
社保卡密码是对的但是提示错误(社保卡上有三个密码)
来源:CCTV生活圈近些年,随着社保和医保的普及,每个人逐步都有了自己的社保卡。社保因为几乎关系到我们每个人的切身利益,所以一直是一个广为关注的话题,人们或多或少都对社保有一些了解,但这些了解大多只停...
锦心似玉中十一娘的母亲怎么死的(十一娘母亲为何被害)
十一娘母亲到底是被谁所害?这是看《锦心似玉》最想知道的答案。这起案件也是整部剧的中心钱,所有剧情发展都是围绕这件事展开。十一娘本无心婚事,夫人主母这样的名号她丝毫不看重,她最想拥有的就是简单的快乐。这...
驾驶证到期都要在多长时间内更换(问题解答驾驶证可以提前多长时间更换新证)
驾驶证可以提前90天换新证件。驾驶证更换注意事项:第一,将违章处理好。存在违章情况去换证,会被交管后台限制换证;第二,进行换证体检。可以在当地车管所体检大厅进行;第三,带好所需资料。需要携带旧驾驶证和...
社保卡密码有几种(社保卡有两个密码)
社保卡,是每一位交社保的人必有的一张卡,但是你真的了解你的社保卡吗?这张卡上有非常重要的密码,关系着大家的社保权益,一起来了解。1社保卡密码社保卡密码分为社保账户密码和金融账户密码。社保账户密码用于办...
社保卡三个密码必须要改(社保卡有两个密码)
社保卡,是每一位交社保的人必有的一张卡,但是你真的了解你的社保卡吗?这张卡上有非常重要的密码,关系着大家的社保权益。今天,为大家介绍下社保卡密码的用途。1社保卡密码社保卡密码分为社保账户密码和金融账户...
一处净化心灵的书店(长沙最美书店④德思勤24小时书店)
湖南日报全媒体记者刘瀚潞通讯员魏晨雨4月27日,夜幕降临,长沙雨花区德思勤城市广场上人流如织。途经嘈杂的酒馆往南走约十步,沿着阶梯缓缓下行,藏在地下的德思勤24小时书店里,灯光柔暖,安然静谧。书店的物...