【UE】属性同步发送和接收源码分析

概述

UE只有Actor类有属性同步功能,Actor开启属性同步的前提是Actor的bReplicated属性为true,属性同步只有Server可以往Client同步,NetDriver类中负责发送和接收属性同步数据,在Server端每帧调用UNetDriver::TickFlush,将要同步的Actor的属性发送到所有连接的Client,在Client每帧调用UNetDriver::TickDispatch接收属性同步消息并修改对应Actor的属性

TickFlush(发送)

首先判断是Server并且客户端连接数量大于0,才会去执行ServerReplicateActors去同步属性
【UE】属性同步发送和接收源码分析_第1张图片
ServerReplicateActors_PrepConnections,将每个客户端连接的ViewTarget设置成PlayerController
【UE】属性同步发送和接收源码分析_第2张图片
构造ConsiderList数组,用于存放经过筛选后的需要复制的Actor,数组大小是用的GetNetworkObjectList().GetActiveObjects().Num(),我们看下为什么用这个设置数组大小
在这里插入图片描述
如果一个Actor打开了复制(Replicates=true),那么就会在NetDriver的NetworkObjectList中储存这个Actor,所以就解释了为什么要用这个数组的大小设置ConsiderList的大小
【UE】属性同步发送和接收源码分析_第3张图片
【UE】属性同步发送和接收源码分析_第4张图片
ServerReplicateActors_BuildConsiderList
依旧是遍历GetNetworkObjectList().GetActiveObjects()
在这里插入图片描述
然后根据一些条件对Actor进行过滤
【UE】属性同步发送和接收源码分析_第5张图片
这里是计算Actor的下一帧同步时间【World->TimeSeconds + UpdateDelayRandomStream.FRand() * ServerTickTime + ActorInfo->OptimalNetUpdateDelta : 1.0f / Actor->NetUpdateFrequency】
【UE】属性同步发送和接收源码分析_第6张图片
将需要同步的Actor加入ConsiderList中,将部分过滤掉的Actor(休眠的、远程权限为空的)从NetworkObjectList移除,下次属性复制时就不会遍历到这些过滤掉的Actor
【UE】属性同步发送和接收源码分析_第7张图片
遍历每一个客户端连接
在这里插入图片描述
ServerReplicateActors_PrioritizeActors
如果Actor还没有建立Channel(每个需要同步的Actor都有一个ActorChannel,用于收发同步消息),且与角色不相关(距离剔除),就跳过,这里的NetCullDistanceSequared就是Actor最大同步距离
在这里插入图片描述
还有只和Owner相关的,但当前连接不是Owner的 以及 休眠的Actor都跳过,最后对Actor按照优先级进行排序
在这里插入图片描述
ServerReplicateActors_ProcessPrioritizedActors
先遍历每个Actor,如果当前Actor没有对应的Channel,则创建一个Channel
【UE】属性同步发送和接收源码分析_第8张图片
去Channel的ReplicateActor执行Actor属性复制
在这里插入图片描述
如果Actor是第一次发送,则还需要包含Actor的创建信息(GUID、Actor的CDO信息),具体可见我的另一篇博文Actor第一次被创建时经历了什么
【UE】属性同步发送和接收源码分析_第9张图片在这里插入图片描述
SendBunch中先创建一个FOutBunch数组,然后添加RPC指针类型参数包【UE】属性同步发送和接收源码分析_第10张图片
最后遍历OutgoingBunches发送包,并记录Bunch在当前Packet中的顺序
在这里插入图片描述
发包就是调用NetConnection::FlushNet中调用LowLevelSebd方法发送的

在这里插入图片描述

TickDisPatch(接收)

待完成

你可能感兴趣的:(ue5,虚幻引擎)