[UE]ReplicationGraph源码浅析
ReplicationGraph源码浅析
简介
UnrealEngine
基本的网络同步在进行同步时需要对每个连接判断每个 Actor
是否需要同步,开销较大;
可以通过实现 Replication
,实现一个不同的 ReplicationDriver
来优化性能;
Replication
将 World
分为多个区域 Grid
,把 Actor
根据所在 Grid
进行分类编组,可以快速找出需要同步的 Actor
,同时确定哪些区域需要进行同步复制。
数据结构
classDiagram class UReplicationGraph
FGlobalActorReplicationInfo
:同步的Actor
信息,包括
Settings
:FClassReplicationInfo
,每个Actor Class
对应的同步配置,包括CullDistance
、ReplicationPeriodFrame
、PriorityScale
等;
Events
:FGlobalActorReplicationEvents Events
,记录休眠状态的改变时,从休眠列表中添加或者移除;
FConnectionReplicationActorInfo
:对于Connection
同步的Actor
信息;
-
ReplicationGraphNode
:GraphNode
基类 -
ReplicationGraphNode_ActorList
:记录同步的Actors
;在StreamingLevelCollection
(以SubLevelName
为Key
的List
)中记录SubLevel
的Actor
,否则在ReplicationActorList
中记录。 -
GlobalGraphNodes
:维护GridSpatialization2D
GraphNode
classDiagram class UReplicationGraphNode { TArray~UReplicationGraphNode*~ AllChildNodes GatherActorListsForConnection() RouteAddNetworkActorToNodes() RouteRemoveNetworkActorToNodes() } UReplicationGraphNode <|-- UReplicationGraphNode_ActorList class UReplicationGraphNode_ActorList { FActorRepListRefView ReplicationActorList } UReplicationGraphNode <|-- UReplicationGraphNode_GridSpatialization2D class UReplicationGraphNode_GridSpatialization2D { TArray~TArray[UReplicationGraphNode_GridCell*]~ Grid; } UReplicationGraphNode <|-- UReplicationGraphNode_AlwaysRelevant class UReplicationGraphNode_AlwaysRelevant{ TArray~UClass*~AlwaysRelevantClasses; } UReplicationGraphNode <|-- UReplicationGraphNode_ActorListFrequencyBuckets UReplicationGraphNode_ActorList <|-- UReplicationGraphNode_GridCell UReplicationGraphNode_ActorList <|-- UReplicationGraphNode_AlwaysRelevant_ForConnection
GridSpatalization2D
:将世界划分为2D
网格,按位置把Actor
分到不同的GridCell
中,按空间管理Actor
是否进行同步,每帧更新GridCell
内的Actor
;GridCell
:ReplicationActorList
缓存着在该GridCell
中的所有静态Actor
,DynamicNodes
里记录动态的Actor
,DormancyNode
里记录休眠的Actor
;AlwaysRelevant
:处理总是发送Net Updates
给 所有Connections
的Actors
;AlwaysRelevant_ForConnection
:处理总是发送Net Updates
给 特定Connection
的Actors
,一般是同步给PlayerController
和ViewTarget
;ActorListFrequencyBuckets
:记录地图格子上的 动态Actor
;
生命周期
Init
graph TD Start(UNetDriver::InitBase) --> A("UNetDriver::SetReplicationDriver") A --> B("UReplicationGraph::InitializeActorsInWorld") B --> | 将World中的同步对象添加到对应GraphNode | C("UReplicationGraph::InitializeForWorld") C --> D("UReplicationGraph::AddNetworkActor(AActor* Actor)") A --> E(InitForNetDriver) E --> F(InitGlobalActorClassSettings) E --> G(InitGlobalGraphNodes)
InitGlobalActorClassSettings
:设置 CulltDistance
、ReplicationPeriodFrame
;注册 Actor
对应的 ClassReplicationInfo
到 GlobalActorReplicationInfoMap
;
InitGlobalGraphNodes
:创建 GridSpatialization2D
、AlwaysRelevant
的 GraphNode
;
InitConnectionGraphNodes
:创建 AlwaysRelevantForConnection
的 GraphNode
;
RouteAddNetworkActorToNodes
:生成 Actor
时,添加 NetworkActor
,分发 Actor
到 GraphNode
;
RouteRemoveNetworkActorToNodes
:销毁 Actor
时,删除 NetworkActor
,通知GraphNode
移除 Actor
;
Repliate
graph TB Start(ServerReplicateActors) --> A(PrepareForReplication) A --> B(GatherActorListsForConnection) B --> C(ReplicateActorListsForConnections_Default) C --> D[ReplicateSingleActor]
-
PrepareForReplication
: 调用GraphNode
的PrepareForReplication
:对于
GridSpatialization2D
,会遍历Actor
,更新其所在的Grid
;对于
AlwaysRelevant
,记录需要同步给所有连接的Actor
; -
GatherActorListsForConnection
: 遍历Connections
收集ReplicationActorList
针对每个
Connection
遍历GlobalGraphNodes
和Connection
的ConnectionGraphNodes
,调用其GatherActorListsForConnection
,收集需要同步给这个Connection
的Actor
;对于
GridSpatialization2D
,通过其GridCellNode
根据Actor
的ViewLocation
收集;收集的
Actor
默认加到GatheredReplicationListsForConnection
里的EActorRepListTypeFlags.Default List
。 -
ReplicateActorListsForConnections_Default
:进行Replicate
的同步检测与排序对
GatheredReplicationListsForConnection
里的Actor
,进行检测;首先排除
Dormancy
、不满足ReplicateFrame
的Actor
,然后根据优先级排序(Distance
、Starvation
、逻辑判定
、Owner & ViewTarget
),将结果缓存在PrioritizedReplicationList
中; -
ReplicateSingleActor
:对排好序的PrioritizedReplicationList
调用ReplicateSingleActor
进行同步。