准备工作
先准备一个勾选了复制的Actor,然后在游戏开始时Spawn这个Actor
源码过程详解
发送属性同步
在NetDriver的TickFlush中发送属性同步的数据
1、ServerReplicateActors_BuildConsiderList 去找到所有需要属性同步的Actor,并根据一些规则过滤掉一部分
2、ServerReplicateActors_PrioritizeActors 按照优先级对Actor进行排序,不可靠的RPC也会被添加到需要发送的Actor数组末尾
3、ServerReplicateActors_ProcessPrioritizedActors 遍历每个需要发送的Actor
这里就可以找到我们的Actor
因为是第一次属性同步的数据,所以这个Actor还没有Channel,就会走到这里的创建Channel的逻辑
Channel就是通道,每个网络复制的Actor都有一个,服务端通过Channel将属性同步的数据发送到客户端
然后走到Channel->ReplicateActor()去执行这个通道的属性同步的操作
第一次属性同步会走到PackageMapClient类的SerializeNewActor,这里的Connection就是客户端连接。
PackageMap每个Server和Client都会有一个,该对象负责Actor和NetworkGUID的双向映射,以及序列化一个Object。
然后走到SerializeObject
调用InternalWriteObject将NetGUID写入到Bunch中,如果有PathName也会一起写入到Bunch中
NetGUID是一个结构体,是网络复制Actor的唯一标识符,用于复制时判断是否为相同的Actor,如果有PathName就根据PathName判断,没有PathName就根据Value判断,PathName就是Actor的路径 + 编号
Archetype:Actor的CDO信息
ActorLevel:Actor所属关卡,同步接受时是根据Level来找Actor的
Location、Scale、Velocity、Rotation这几个Actor属性
匿名函数ConditionallySerializeQuantizedVector将Location、Rotation等属性序列化到Bunch中
然后去发送属性同步Packet
接收属性同步
堆栈
1、是Actor的第一次属性同步,所以接收时客户端还没有这个Actor
也是这六个属性
SerializeObject去序列化Actor数据到Archetype
读取到ActorLevel、Location、Rotation等信息
如果Actor为空,Archetype(CDO)不为空,就去生成Actor,并附带位置、旋转、所在关卡等信息
如果Actor生成成功再去添加速度、缩放属性
去客户端注册这个Actor,也就是去ObjectLookup数组中添加这个Actor,下一次再有属性同步数据时就可以找到这个Actor了
如果是新生成的Actor执行PostNetInit(),去执行Actor的BeginPlay
至此一个Actor的第一次属性复制的流程结束