UE4.27, 揣摩源码, 网络同步 (二) 同步

3.  同步指的是UE里服务器对客户端的单向数据同步

4.  Actor同步

  4.1.  堆栈调用

 

    UNetDriver::TickFlush

      // 作为服务端的时候将调用该函数

      UNetDriver::ServerReplicateActors

        ServerReplicateActors_PrepConnections

          // 1.ViewTarget从PlayerController赋给NetConnection和ChildNetConnection

          // 2.计算这个tick要处理同步的客户端连接数目

             // 具体而言,基准是GEngine的一个设定值

          // 因为这个设定值按秒计算,自然地乘算一个间隔时长,如果这一帧clientconnection计数为零,会把这帧的间隔时长非持存地向后传递一帧

          // Lan的话还会再乘双倍

          // 最后的值和总的clientconnection计数取最小值

        ServerReplicateActors_BuildConsiderList

          // 对FNetworkObjectInfo数组进行处理,其中大部分是记录某actor的这次和下次的同步时间

          // 值得注意的是,下次的同步时间是区间随机的,我能想到的理由是 平衡同时同步的流量压力 或 使玩家体验更加正常

        /** ClientConnection遍历循环 **/

          ServerReplicateActors_PrioritizeActors

          // 优先级排序

          ServerReplicateActors_ProcessPrioritizedActors

          // 处理实际的 Actor 同步

            // 一系列的创建ActorChannel

            ReplicateActor

              UPackageMapClient::SerializeNewActor

        /** 循环完毕 **/

        /** 5035 ~ 5047 **/

        // 将尚未处理的客户端连接放在数组的前面,让下一帧优先处理  

   4.2.  流程详细介绍

    4.2.1.  同步的起点

        同步总是先从Actor同步开始的,这一点可以从我们总是SpawnActor在服务器上,然后同步到客户端上的这一流程看出

        细致地来说,同步Actor需要将Actor的属性给同步给客户端上的Actor,而第一次同步还需要在客户端上创建Actor

    4.2.2.  第一次同步Actor

        需要说明的是,服务器上创建了actor,同步之前,客户端上是没有这个actor的,所以第一次同步需要在客户端上spawn一个同样的actor

        spawnactor所需的信息里,uobject是必不可少的。

        服务器如何告诉客户端这个uobject的信息呢?我们之前已经体会了ue的正反序列化,假如我们处理的uobject是正常序列化存储在本地的,对于服务器和客户端来说,uobject的资源路径,

        实质上也就是它们外部链最外层的那个package是在同样的相对路径下的,因此我们不必要传输一整个uobject信息,只需要传递这个资源路径信息path即可

        然而第一次同步确实只需要这个path,但是第二次第三次呢?这个path有没有进一步节约流量的可能?更严重的问题,actor实例化出来后,和资源路径的对应关系不必然是一对一的,也可能是多对一的

        为了解决对应问题和节约流量,ue设计了UPackageMapClient来管理这些分布在客户端和服务器上的具有同步关系的actor,最关键的对应关系是NetGUID和ClassPath

        服务器将首先传递ClassPath和服务器端对这个actor的唯一标识NetGUID给客户端,客户端凭借ClassPath完成spawn,并且建立接受到的NetGUID和这个新actor的映射关系

        最后的效果就是,除了第一次需要传递ClassPath来完成spawn,后续的同步都可以凭借NGUID来达到在不同端上指定具有同一同步关系的actor

 

5.  属性同步
  5.1.  堆栈调用

    UNetDriver::TickFlush

      UNetDriver::ServerReplicateActors

        ServerReplicateActors_PrepConnections

        ServerReplicateActors_BuildConsiderList

        /** ClientConnection遍历循环 **/

          ServerReplicateActors_PrioritizeActors

          ServerReplicateActors_ProcessPrioritizedActors

            ReplicateActor

              ReplicateProperties

                UpdateChangelistMgr

                  CompareProperties

                  // 遍历每个UProperty检查是否有变化

                // 如果有变化

                SendProperties

        /** 循环完毕 **/

posted @ 2025-01-05 19:50  在找饭吃的陈  阅读(108)  评论(0)    收藏  举报