Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >UE4 ReplicationGraph分析

UE4 ReplicationGraph分析

原创
作者头像
小伏羲
发布于 2018-12-18 11:21:00
发布于 2018-12-18 11:21:00
4.6K0
举报
文章被收录于专栏:UE4技术专场UE4技术专场

UE4 ReplicationGraph分析

老版本网络系统

总体思路

  • 所有Actor都会添加到网络列表中,每次更新的时候都是从这个Actor列表中遍历,根据不同的条件,确定每个链接的客户端需要同步的Actor列表,然后同步数据

流程图

老流程图.png
老流程图.png

添加

  • 生成Actor的时候直接调用AddNetworkActor函数,添加进workObjectlist中
代码语言:txt
AI代码解释
复制
void UWorld::AddNetworkActor( AActor\* Actor )

{

    if ( Actor == nullptr )

    {

        return;

    }



    if ( Actor->IsPendingKill() ) 

    {

        return;

    }



    if ( !ContainsLevel(Actor->GetLevel()) )

    {

        return;

    }



    ForEachNetDriver(GEngine, this, [Actor](UNetDriver\* const Driver)

    {

        if (Driver != nullptr)

        {

            // Special case the demo net driver, since actors currently only have one associated NetDriverName.

            Driver->GetNetworkObjectList().FindOrAdd(Actor, Driver->NetDriverName);

        }

    });

}

详细同步过程

代码语言:txt
AI代码解释
复制
// 总入口函数

int32 UNetDriver::ServerReplicateActors(float DeltaSeconds)

{

    // 确定当前的连接客户端

    ServerReplicateActors\_PrepConnections



    //确定同步列表(性能瓶颈点)

    ServerReplicateActors\_BuildConsiderList



    //对Actor列表进行优先级排序(性能瓶颈点)

    ServerReplicateActors\_PrioritizeActors    



    //处理排序过后的Actor列表(这里会进行最终的同步操作)

    ServerReplicateActors\_ProcessPrioritizedActors

}

优化方式

  • 裁剪距离降低
  • 降低更新频率

核心问题

  • 每次同步的计算量是ConnectionList*NetObjList,Actor列表庞大,比对计算的时候性能消耗是主要瓶颈点
  • 优化困难,上述优化都是有损优化,降低了客户

新版本网络系统

总体思路

  • 根据类型和状态对Actor进行节点划分,每次针对当前Connection只检查所在Grid内对象的信息来大大降低整个Replication的计算量,节省CPU时间

流程图

新流程图.png
新流程图.png

结构图

同步图表.jpg
同步图表.jpg
  • UReplicationGraph: 同步图表,NetDriver的网络分发入口
  • GridSpatialization2D:按照2D空间划分的同步节点
  • Playerstate:与状态有关的节点,比如限制更新频率的对象
  • Always Relevant(All): 与所有的链接都有相关性
  • Tear off:类似于OwnerRelevant,只同步给主客户端,不同步给模拟客户端
  • Always Relevant(Connection):只与某一个链接具有相关性,比如走进某一个区域点亮一盏灯,只对这个链接有作用
  • Always Relevant(team):和队友都有关的链接行,比如复活次数等等
  • Static:静态同步对象(可破坏物件)
  • Dynamic:可以移动的同步对象
  • Dormant: 休眠对象
  • Streaming:和关卡有关的对象,只有关卡加载了才会进行同步

添加

  • 生成Actor的时候通过调用各个类型节点的AddNetworkActor,分发Actor的存储
代码语言:txt
AI代码解释
复制
void UNetDriver::AddNetworkActor(AActor\* Actor)

{

    GetNetworkObjectList().FindOrAdd(Actor, NetDriverName);

    if (ReplicationDriver)

    {

        ReplicationDriver->AddNetworkActor(Actor);

    }

}
  • Gird 2D结构
2D结构.png
2D结构.png
代码语言:txt
AI代码解释
复制
- GridSpatialization2D 会按照cellsize划分为多个网格
代码语言:txt
AI代码解释
复制
- AddActo
代码语言:txt
AI代码解释
复制
    - 存在
代码语言:txt
AI代码解释
复制
        - 根据种类添加到对应的列表中,静态,动态,休眠等等
代码语言:txt
AI代码解释
复制
        - 静态动态中有划分为是否是属于streamingLevel中等
代码语言:txt
AI代码解释
复制
    - 不存在网格
代码语言:txt
AI代码解释
复制
        - 创建网格(和裁剪距离,Cellsize都有关系),重复网格存在的添加步骤
代码语言:txt
AI代码解释
复制
- 更新
代码语言:txt
AI代码解释
复制
    - 超过现有的网格边界
代码语言:txt
AI代码解释
复制
        - 创建新的网格
代码语言:txt
AI代码解释
复制
        - 刷新网格中的Actorlist
代码语言:txt
AI代码解释
复制
    - 根据动态Actor位置刷新网格中的actorList

详细同步过程

  • 服务器tick调用网络同步,直接分发到同步图表类中,在这个类里面做同步的Actor同步前的处理操作,但是最终的Actor同步过程还是走原有的逻辑
代码语言:txt
AI代码解释
复制
// 总入口函数

int32 UNetDriver::ServerReplicateActors(float DeltaSeconds)

{

    // 转发到同步图表类中

    ReplicationDriver->ServerReplicateActors(DeltaSeconds);

    int32 UReplicationGraph::ServerReplicateActors(float DeltaSeconds)

    {

        //各个节点的前期同步准备工作(对于空间划分的Grid主要是刷新各个网格中的Actor列表)

        for (UReplicationGraphNode\* Node : PrepareForReplicationNodes)

        {

            Node->PrepareForReplication();

        }

        // 处理各个链接的客户端

        for (UNetReplicationGraphConnection\* ConnectionManager: Connections)

        {

            //公共节点中需要的Actor列表

            for (UReplicationGraphNode\* Node : GlobalGraphNodes)

            {

                Node->GatherActorListsForConnection(Parameters);

            }

            //相关联的节点中的Actor列表

            for (UReplicationGraphNode\* Node : ConnectionManager->ConnectionGraphNodes)

            {

                Node->GatherActorListsForConnection(Parameters);

            }

            //真正Actor进行同步的地方,剩下的和老版本网络流程一致

            ReplicateSingleActo

        }

    }

}

新版本网络使用步骤

  • 自己重写ReplicationGraph
  • 添加自己的网格节点划分类型
  • 两种启动方式
代码语言:txt
AI代码解释
复制
- DefaultEngine.ini 配置自己重写的同步图表类
代码语言:txt
AI代码解释
复制
    - [/Script/OnlineSubsystemUtils.IpNetDriver]

ReplicationDriverClassName="/Script/ProjectName.ClassName"

代码语言:txt
AI代码解释
复制
- 创建委托 
代码语言:txt
AI代码解释
复制
        UReplicationDriver::CreateReplicationDriverDelegate().BindLambda([](UNetDriver\* ForNetDriver, const FURL& URL, UWorld\* World) -> UReplicationDriver\*

            {

                return NewObject<UMyReplicationDriverClass>(GetTransientPackage());

            });

优化方式

  • 通过详细的网格划分减少每次需要进行计算的Actor数量,提升性能

核心问题

  • 对于小场景来说用处不大,很有可能所有的Actor都在同一个网格中
  • 每次同步前都需要刷新网格中acto

新老版本对比(数据相关的需要自己搭建场景获取)

| Type | 标准网络 | Graph网络 |

|---------- |:-------------:|:-------------:|

| ActorList | 全量存储 | 按类型划分存储|

| 自定义网络同步 | 不支持 | 支持|

| 优化方式 | 有损效果,降频,降低裁剪距离 | 细致的网格种类划分|

| 性能 | 性能较差,随着客户端和actor的增长,呈现几何增长的性能消耗 | 性能和网格的划分密切相关(fortnite官方数据此处性能消耗降低75%)|

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
UE4 Actor生命周期 SpawnActor DestroyActor剖析「建议收藏」
第一部分,从编辑器点击Play开始分析World里面全部的Actor的Spawn流程,分析到调用BeginPlay结束
全栈程序员站长
2022/11/01
3.1K0
Unreal TickFunc调度
Tick在计算机领域并没有很好的中文翻译,英汉词典里的解释是很短的一段时间,或者时钟的一次滴答。
JohnYao
2022/06/29
1.3K0
Unreal TickFunc调度
UE网络通信(二) 相关性
网络相关性在传统的MMORPG游戏中有另外一个名称AOI(Area Of Intrest)。
JohnYao
2022/06/29
1.2K0
UE网络通信(二) 相关性
UE4新手常用C++API
//C++暴露给蓝图可编辑 UCLASS(Blueprintable) //创建FString FString::Printf(TEXT("aa bb")); //蓝图调用变量 UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) //限制条件范围 meta = (ClampMin=0.1,ClampMax = 100) //蓝图识别组件 UPROPERTY(EditAnywhere, BlueprintReadWrite
Ning@
2021/11/10
3.6K0
UE网络通信(一) 概述
现在市面上,绝大多数的游戏都是网络游戏。客户端和服务器之间通过网络进行通信,同步游戏内的信息。这个系列的文章以Unreal Engine 4.26版本为基础,试图讲解下UE4网络通信的相关功能。
JohnYao
2022/06/29
2.4K0
UE网络通信(一)  概述
UE网络通信(四)RPC&移动通信
距离上一次发表《UE网络通信》系列的文章已经过去了一年多。这段时间,UE5.0在2022年4月发布;UE5.1在2022年11月发布。好在新版本,引擎在同步方面尚未做大的变更;之前立的关于RPC,底层协议的写作flag,还是可以继续进行。
JohnYao
2023/04/28
2.7K0
UE网络通信(四)RPC&移动通信
UE4学习笔记: Replication
Actors 客户端复制actor被spawn出来时, 只有Location和Rotation在PreBeginPlay()和PostBeginPlay()时是合法的 被复制的Actor只有在服务器关闭他们的复制通道时才被销毁 Actor的属性复制是可靠的. 只会从服务器往客户端同步 FReplicationFlags 属性 描述 bNetOwner 在目标机器上被PlayerController控制 bNetInitial 初始网络更新 bNetSimulated Actor是 RemoteRole 模拟
逍遥剑客
2018/05/21
2.2K0
UE4网络模块解析(一)
客户端所有的操作如击杀等都需要传到中央服务器来运算,得到的运算结果下发到各个客户端。服务器是UE4多人游戏的重要组成部分。它做出所有重要决策,包含所有权威状态,处理客户端连接,前往新地图,处理开始比赛、结束比赛等整个游戏流程。
玖柒的小窝
2021/12/14
7260
ue4动态加载模型(unity资源加载)
2.假如遇到调试模式下程序运行正常,但是打包出来后程序crash,可以查看log: Saved/Logs/filename/log
全栈程序员站长
2022/07/29
1.6K0
ue4动态加载模型(unity资源加载)
UE4 常见的宏UFUNCTION-函数说明符
函数说明符: BlueprintAuthorityOnly  如果在具有网络权限的计算机(服务器,专用服务器或单人游戏)上运行,此功能只能从Blueprint代码执行,如无网络权限,则该函数将不会从蓝图代码中执行
Ning@
2021/11/10
2.6K0
UE4 常见的宏UFUNCTION-函数说明符
UE4 Module 新建与使用
UE 的 module 是一堆 C++ 类和代码的集合,类似于 DLL,而 UE 本身也是由一堆 module 构成的。将代码拆分为 module 的目的是:
zhiruili
2023/10/20
8760
UE4
类命名(基础类actor、Uobject) 派生自 Actor 的类带有 A 前缀,如AController。 派生自 Object 的类带有 U 前缀,如UComponent。 Enums 的前缀是 E,如EFortificationType。 Interface 的前缀通常是 I,如IAbilitySystemInterface。 Template 的前缀是 T,如TArray。 派生自 SWidget 的类(Slate UI)带有前缀 S,如SButton。 其他类的前缀为字母F ,
sofu456
2019/07/09
3.5K0
UE4 多人游戏服务器探索
大家好,今天给大家带来一篇利用虚幻的专用服务器简称ds服务器,来实现一个多人网络同步的 Demo。在联网游戏中,如何实现网络同步一直是一个复杂和困难的话题,为此,虚幻引擎将自己多年来的开发经验汇总然后推出了专用服务器 Dedicated Server,接下来就让我们一起来看看吧!
HelloWorld杰少
2022/08/04
3.3K0
UE4 多人游戏服务器探索
ue4 插件开发(ue4性能优化)
UE4引擎和UE4项目是由各个模块组成的,其主要编程语言是C++。 插件也是一个模块,说到插件必须讲到耦合性与独立性,耦合性是对模块间关联程度的度量,模块间关联越强,则耦合性强,独立性差。 庞大的UE4引擎各模块相互参差作用,所以想要读懂并拆解并非易事,而创建UE4游戏项目实则只引入了引擎的部分模块,再想想如果很多游戏项目都需要用到这一个自定义功能时,是不是每个项目都要开发一次这个功能,个人或者一家公司内部还好,只要把项目代码复制给另一个项目即可,但是全球这么多的UE4开发者怎么办,开发者的结晶势必要发挥它最大的用处,把自己的研发成果分享出去,为了解决这类问题,就要使得模块独立起来,那么UE4插件就该闪亮登场了。
全栈程序员站长
2022/07/29
3.5K0
ue4 插件开发(ue4性能优化)
基于Scala的并发编程模型Akka
        Akka 是 JVM 平台上构建高并发、分布式和容错应用的工具包和运行时环境。Akka用Scala 语言编写,同时提供了 Scala 、JAVA 的开发接口。
Java架构师必看
2021/05/14
1.3K0
基于Scala的并发编程模型Akka
UE运行时动态生成自定义物理形状碰撞检测
在MMORPG游戏中,针对一些范围伤害的计算,会涉及到碰撞/相交检测。在传统的2D或2.5D游戏中,或者要求不那么精确的3D游戏中,这种相交检测可以简化为平面上圆形与各种形状(如圆形、矩形、扇形等)是否相交的检测^1^,但是当考虑上飞行、跳跃等逻辑后,就必须进行3D空间的相交检测了,此时就需要借助物理引擎的功能。
Kill Console
2022/08/19
3.7K0
UE4之UFUNCTION介绍
UObject 或蓝图函数库可将成员函数声明为UFunction,方法是将 UFUNCTION 宏放在头文件中函数声明上方的行中。
李小白是一只喵
2021/05/13
2.5K0
UE4的资源管理
开发一个大型游戏,因为美术资源和游戏数据都是海量的,不可能把所有的数据都放在内存里。本身玩家的游戏设备内存大小也是有限的,而大型游戏尤其是3A大作下载下来都几十G上百G,内存根本放不下。因此就需要有一个手段,可以在需要用的时候把他们加载进来,不需要的时候卸载掉,让内存尽可能的节省,把内存尽可能用到最合适的地方。同时又要避免内存和硬盘上的资源频繁加载卸载耗时影响用户体验。可想而知,要做好资源管理,是一件非常麻烦又非常有必要的事情。
quabqi
2021/11/04
3.4K1
UE4的资源管理
Unreal 01 - LoadMap
FCoreUObjectDelegates::PreLoadMap.Broadcast(URL.Map); 回调事件通知
Reck Zhang
2021/08/11
1.3K0
大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目
  模拟实现基于文本界面的《客户信息管理软件》。   该软件 scala 能够实现对客户对象的插入、修改、删除、显示、查询(用 ArrayBuffer 或者 ListBuffer 实现),并能够打印客户明细表。
黑泽君
2019/04/17
2K0
大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目
相关推荐
UE4 Actor生命周期 SpawnActor DestroyActor剖析「建议收藏」
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档