目录:第九艺术-目录
目录
ReplicationDriver在NetDriver中的写法
ReplicationEvent:DormancyFlush/ForceNetUpdate/DormancyChange
这部分主要是自己之前看有关部分整理的笔记,对应源码看比较好
ReplicationDriver在NetDriver中的写法
用ReplicationGraph替代旧的同步系统的话,重新直接调用ReplicationDriver对应接口的方法之后,直接return,强制截断
比如最主要的接口
- UNetDriver::ServerReplicateActors
- UNetDriver::ProcessRemoteFunction
- ...
基础类:
UReplicationGraph : public UReplicationDriver :public UObject
UReplicationGraphNode : public UObject
UNetReplicationGraphConnection : public UReplicationConnectionDriver :public UObject
默认情况下,
一个 Driver,有一个GlobalNodes数组,有多个Connection
每个Connection,有一个 ConnectionNodes数组,另外多一个TearOffNode,用于TearOff这个Connection里面的Actor
当然这些结构都可以通过重载自定义
辅助类
FReplicationGraphGlobalData
所有Connection共享的,全graph全局数据
FClassReplicationInfo
每个Class的配置的复制属性,比如优先级,同步裁剪距离,ReplicationPeriodFrame等等
FGlobalActorReplicationInfo
每个Actor的全 graph共享的数据,比如 上次同步时间,WorldLocation,DependentActorList,FastSharedReplicationInfo等等
Engine Fix:
Info.ReplicationPeriodFrame 最大间隔是255帧同步一次,因为它是 uint8类型,超过255,会数字回绕,所以Static和Dynamic的NetUpdateFrequency 设置了很大没用
在ShooterGame或者官方默认的BasicReplicaGraph里,周期的计算是
Info.ReplicationPeriodFrame = FMath::Max<uint32>((uint32)FMath::RoundToFloat(ServerMaxTickRate / CDO->NetUpdateFrequency), 1);
虽然用了 uint,但其实没用,因为
/** Per-Class actor data about how the actor replicates */
struct FClassReplicationInfo
{
...
uint8 ReplicationPeriodFrame = 1;
}
所以最大256,比如上面 NetUpdateFrequency = 0.1,ServerMaxTickRate 默认30,那除下来300,回绕变成了 44,所以实际是44帧同步一次,这也解释了为什么默认一堆Actor的debug显示同步周期是44
所以这里我改成了,直接写好最大255,起码没有隐式错误
Info.ReplicationPeriodFrame = FMath::Max<uint8>(FMath::Min<uint32>((uint32)FMath::RoundToFloat(ServerMaxTickRate / CDO->NetUpdateFrequency), 255), 1);
也给官方提交了 pull request,官方也修改了把类型改成了uint16,项目比较急的话,可以自己从github上拿,自己先本地merge。
ReplicationEvent:DormancyFlush/ForceNetUpdate/DormancyChange
struct FGlobalActorReplicationEvents
{
FNotifyActorChangeDormancy DormancyChange;
FNotifyActorFlushDormancy DormancyFlush; // This delegate is cleared after broadcasting
FNotifyActorForceNetUpdate ForceNetUpdate;
};
DormancyChange
发生在
- AActor::SetNetDormancy调用之后
- 会调用UNetDriver::NotifyActorDormancyChange
- 设置 Actor GlobalInfo.bWantsToBeDormant,然后Broadcast事件
- 事件 会被 UReplicationGraphNode_GridCell 收到,调用对应 OnStaticActorNetDormancyChange
- UReplicationGraphNode_GridSpatialization2D也会收到,调用OnNetDormancyChange
- 设置 Actor GlobalInfo.bWantsToBeDormant,然后Broadcast事件
- 之后,还会调