一.帧同步,属性同步,状态同步
DS是一种网络拓扑结构,专用服务器 到 每个客户端。
而帧同步,属性同步,状态同步,更应该说是是数据同步方式,且属性同步很多时候是为了达到状态同步的一种手段。
它们其实是不同维度的东西,我刚开始接触的时候就搞混了,UE 的 大部分实现方案,都是用的属性同步,状态同步两者都用。单独用
在UE的网络模型里,大致是这样分类如下:
Replication(状态同步)
├── Property Replication(属性)
└── Movement Replication(移动状态)
RPC(事件同步)
结合下面的案例如果再分细一点,如下:
Actor Replication
├── Replicates
└── Replicate Movement
Property Replication
├── Replicated
└── RepNotify
RPC
├── Server RPC
├── Client RPC
└── Multicast RPC
二.UE GamePlay框架在网络里的 存在位置验证

GameMode 验证准备

在最开始的时候打印一下,因为它就像顶图所示,只存在于服务器端。
GameState 验证准备
同理可推断GameState,在服务器,两个客户端,三方都存在。一份但都会产生,应该会打印3份。

PlayerState
这里由于有两个客户端玩家数据需要存储,所以有两份。但是三方都有,按理来说就该有6份

Pawn
这里由于有两个客户端所以有两份。但是三方都有,按理来说就该有6份

PlayerController
这里就比较容易混淆了,它只在自己的客户端和服务器存在,所以有两份。服务器会产生所有的,但每个客户端,你就只能看到自己的。看上图就很容易理解,一份在自己客户端,一份在服务器上。这里两个客户端,2*2 = 4 份

而UMG 和 HUD
都只会在 自己的客户端看到,这里就当一个东西验证。这里两个客户端,2*1 = 2 份

开始验证


无论是从屏幕还是日志的输出的验证,不要严格卡时序,玩家1,玩家2连接有部分穿插的可能,还有千万别看什么Servrer0,1 这些序号,容易被误导:
服务器上,一开始Server创建GameMode,然后GameState。自己的
然后创建Server:PlayerState,Server:PlayController,Server:Pawn,三剑客, 这个是玩家1出现创建在服务器上的,别人的。

客户端 1上:先产生 PlayerController,HUD,Pawn,GameState,PlayerState,这个五个是自己的。

更有意思的在后面,当第二个玩家连接上后,服务端 又产生了一个Server:PlayerState,Server:PlayController,Server:Pawn。这是第二个客户端出现,在服务器 上生成的,和前面第一个出现时,服务器上的反应一样的三剑客。
客户端2上:自身产生 Pawn,PlayerState,PlayerController,HUD,GameState,这五个也是自己的。再产生客户端1的Pawn,PlayerState

客户端1: 再产生客户端2 的Pawn ,PlayerState 。完美闭环,验证了那个三圈图。
他们的顺序也许会没那么严丝合缝,它无法保障时序,但是整体逻辑,整体出现的次数就是正确的。GameMode 最开始1次,GameState3次,PlayerState 6次,PlayerController 4次,Pawn 6次,HUD 2次。
三.客户端的默认加载
客户端会默认加载全部,但不是每个对象都要进行同步。服务器一端不会渲染,只运行逻辑。
随便一个Actor物体,默认会勾选Net Load on Client。意思这个Actor会在客户端加载出来

一个Character会有,默认会勾选更多的同步选项。不仅会勾选Net Load on Client,还会多勾选
Replacte Movenent 这个是角色移动(UE内置的一套简单同步,更多由于继承Pawn才勾选的,编辑器只显示CDO状态,运行时,初始化时会自动把自己的 Replicate Movement 关掉 。会有更复杂的移动同步机制**CharacterMovementComponent(CMC)** 来接管一切)。Replicates 也勾选。
如果仅开启了 Replicates 而没有开 Replicate Movement,CMC 只会进行"空同步",客户端上的角色会被定位在服务器位置,但不会跟随服务器平滑移动。
Replicates(复制) 是 Unreal Engine 网络系统中每个 Actor 都有的一个核心开关,全称是 bReplicates。它的作用一句话概括:决定这个 Actor 是否要从服务器"复制"(同步)到所有客户端。
-
勾选(True):这个 Actor 由服务器权威管理,服务器会把它(及其位置、动画、需要同步的属性)自动发送给所有连接的客户端。每个客户端上都能看到这个 Actor 并保持同步。
-
不勾选(False):这个 Actor 只存在于生成它的那一台机器上(通常是服务器,或者是某个客户端的纯本地 Actor),其他机器完全不知道它的存在,也就看不到、碰不到。

Net Load on Client 不勾选,那我们客户端就没有。自己做个实验即可,在场景实例里把NetLoadOnClient取消。把模式改为ListentSever

就会同时有两个窗口
Sever 里看得到圆球

Client1 因为没勾选客户端加载所以没有圆球

增加移动后,发现。即使客户端没加载,但碰撞还在,服务器才是权威。


四、服务器控制Actor的产生 和 销毁
1.先加一个触发机关的Actor逻辑,Box碰撞默认的碰撞通道,BeginOverlap的时候输出。


碰撞后,最上面一个Sever:Box,一个Client:Box。说明服务器,和客户端都碰撞了,触发了一次。

创造这个检测类BP_RightReplicate,球体 ,具有Replicates的属性。

增加逻辑碰撞后,上方产生球体。

3.如果直接生成,无论几个客户端都,碰撞几次会发现,客户端是服务器上的两倍。这是因为,服务器生成了一个,客户端1本地也生成了一个。客户端二,也是同步了服务器的,但是我们控制的是客户端1,为啥客户端2 也碰撞了,也产生了本地的。我最开始也有这个疑问,因为Client2
也有:Character_A(BP_TestNet)的代理(Simulated Proxy)。

再进一步总结,Authority有最终决定权,AutonomousProxy本地控制,SimulatedProxy远程同步对象。每次碰撞都有三个起作用的碰撞,Authority 碰撞后服务器生成,AutonomousProxy本地控制碰撞后客户端1生成 。SimulatedProxy远程同步,客户端2 也自己在生成自己的。 只是服务器端的,大家都会同步到客户端,所以看到两个。
4.最好在碰撞时,判断是否是服务器的,只在服务器执行碰撞后生成,这样就只有服务器权威的了,一次一个。只在服务器上生成,就对了。

五、Role 翻译 职能,角色
在行为同步时,我们对关键性行为一般分为最简单的三类:
1.客户端 呼叫 服务器执行
2.服务器呼叫所有客户端执行
3.服务器呼叫指定客户但执行
实际情况下,我们一般会组合起来使用
上述行为行为同步是基于RPC的。行为同步是需要开启网络复制 ,并且有合理的权限。
而这个权限,会由Actor的Role 决定。翻译过来就是这个Actor的地位,角色。
记住这三个东西,Authority 权威端、AutonomousProxy 主控端、SimulatedProxy 模拟端
Authority 权威端 只能在服务器,才能有这样的权威。
分类
1.开启网络复制后,根据所处机器终端的位置不同 ,可以获得不同身份。
当前机器的身份,称之为 LocalRole。是当前机器怎么看待自己这个Actor。
在远端机器的身份,称之为RemoteRole。是当前机器 看到的远端机器怎么看待这个 Actor。
终端可以是服务器,远端是客户端。也可以是终端是客户端,那么远端就是服务器。并不固定,重要的是你在哪,理清概念。
2.Role

Authority 权威端,只在服务器端有这个角色
AutonomousProxy 主控端 可以大至理解为自己电脑上的客户端,本玩家。
SimulatedProxy 模拟端 可以大至理解为其它电脑上的客户端,其它玩家。
LocalRole 身份说明
|-----------------|---------------|------------------------|
| LocalRole\位置 | 服务器 | 客户端 |
| SimulatedProxy | 不存在 | 服务器在当前引擎实例中模拟的玩家角色(模拟) |
| AutonomousProxy | 不存在 | 当前引擎实例中由真人操控的角色 (主机代理) |
| Authority | 服务器拥有复制权限的权威性 | 不存在 |
通过获取当前对象的LoaclRole,就可以判定对象所在位置。
RemoteRole 是当前机器 看到的远端机器怎么看待这个 Actor。
|-----------------|------------------|-------------------|
| RemoteRole\位置 | 服务器 | 客户端 |
| SimulatedProxy | 当前Actor在远端是模拟的 | 不存在 |
| AutonomousProxy | 当前Actor自主权操控权在远端 | 不存在 |
| Authority | 不存在 | 拥有当前Actor复制权限的权威性 |
3.验证
创建一个BP_NetCharacter,一个BP_NetGameMode。设置好WorldSetting
Character 打印测试LoacalRole,RemoteRole


在单机模式下,只有一个机器客户端服务器都是自己,无真正意义客户端只输出一次。终端时服务器Authority,远端客户端也是自己就是模拟Simulated

而在客户端服务器模式下时,服务器的Character先输出,终端是Authority,服务器远端是 模拟Simulated的角色。
客户端的Character再输出,终端是AutomousProxy(主机代理),客户端自己控制,但远端是服务器也就是Authority。 如果不受控制,也会是Simulated。


现在再增加一个客户端,进行验证。

现在就是一个服务器,两个客户端。服务器端线打印自己Authority, 远端 Simulated很正常;接着客户端,打印自己是Autonomous 代理主机,远端服务器Authority。另一个客户端,也会出现,它在本客户端上就是Simulated,远端是服务器Authority。
补充:因为PIE模式编辑器的关系,所有打印会合并竟来。但不要被误导,服务器并没有再产生一个character在客户端1。那个世界只有玩家1,玩家2两个character。