Bootstrap

UE5动态加载Pak并完成网络同步

前言

引擎版本 UE 5.4源码

需求:多人游戏,多端异步下载Pak包。服务器下载完成后,加载Pak中的网路同步Actor,多端正确执行网络同步。

问题描述:

Pak包中存在一个网络同步的Actor,DS和客户端异步的下载Pak并挂载,服务器生成Actor后进行网络同步。客户端由于Pak资源还未下载完成而无法同步。

解决方法:

1.服务器生成Actor后记录Actor的NetCache信息,重点是Actor的NetGuid和PathName,还需要记录CDO和other的FGuid和PathName。

2.客户端加载Pak完成后,向DS请求第一步中的数据,将数据写入本地的NetCache中。

3.客户端通知服务器,将ActorChannel断开,促使ActorChannel重建,以完成网络同步。

详解:

我们知道每个Actor都需要一个ActorChannel来进行同步数据的传输,每个Actor都有一个唯一的NetGuid。当首次发生同步时(服务器创建一个勾选了Replicated的Actor)ActorChannel会被创建,并将Actor的数据序列化后发送给客户端,客户端接受到后会进行反序列化,解析数据后在本地客户端创建Actor,完成同步连接。
在这里插入图片描述
在问题中提到的客户端由于Pak资源还未下载完成而无法同步,是由于当客户端解析序列化信息后,试图根据信息中的PathName生成对应的Actor,发现生成失败(因为还没下载完)。而当客户端下载完成后,也不会再去生成一遍。

所以如果我们想让这个Actor能正确的被同步,就需要从服务器中获取所需要的同步数据,在客户端下载完成后,重新建立ActorChannel。

在每个端中有一个UNetDriver来管理网络连接。其中包含成员变量TSharedPtr< class FNetGUIDCache > GuidCache。
在这里插入图片描述
FNetGUIDCache中有TMap< FNetworkGUID, FNetGuidCacheObject > ObjectLookup 用来存储网络同步object的缓存信息。
在这里插入图片描述
FNetGuidCacheObject的结构:
在这里插入图片描述
实际操作中,我们需要在服务器创建这个Actor后,获取它的一系列数据包括:

Actor对象的Netguid,PathName;

Actor CDO对象的Netguid,PathName;

Actor CDO对象的Outer的Netguid,PathName;

将这些数据进行存储,当客户端也完成了pak的下载和加载后,通知服务器,把这些数据传输给客户端,并重新建立ActorChannel。

测试代码:

/// GUID缓存数据类型
/// </summary>
UENUM(BlueprintType)
enum
;