序言
现在市面上,绝大多数的游戏都是网络游戏。客户端和服务器之间通过网络进行通信,同步游戏内的信息。这个系列的文章以Unreal Engine 4.26版本为基础,试图讲解下UE4网络通信的相关功能。
UE4 网络同步概述
UE4网络同步是建立在虚幻对象, Gameplay(游戏玩法)体系之上的。所以在学习UE4网络同步之前,要对虚幻的UObject以及Gameplay体系有个基础的了解。
Gameplay类介绍
简单的讲,UE4在C 的基础上,构建了自己的UObject体系,GamePlay相关的对象都从UObject继承。
最主要的Gameplay对象类是AActor,他是可以被放置到场景(ULevel)中的对象,所有以大些字母A命名的类AXXX都是Actor类。
AActor又由Component构成,所有的Component都从UActorComponent派生而来。
网络通信概述
从宏观层面,UE4的网络层(UNetDriver)会为每个客户端建立相应的连接UNetConnection。
每个连接的同步是以Actor进行组织的。每个Actor有自己独立的UActorChannel负责客户端和服务器之间的通信。基于Actor Channel又有两种不同的同步方法。
- 属性同步
- RPC调用
属性同步保证的是最终状态一致。RPC分为可靠的RPC调用和非可靠RPC调用。可靠的RPC调用是保序的。
UE4使用的是UDP协议。为什么不使用TCP呢?因为TCP本身是一个严格保序的单通道协议,某个TCP的报文段的丢失会导致其后续报文段不能及时反馈给应用层。
UDP是数据报协议,利用它我们可以实现多通道。如前面概述所说,UE4为每个Actor构建一个通信通道。某Actor X的通信包的丢失不会影响到其他的Actor。
每个具体通道,又有可靠通信通道和非可靠通信通道。只有可靠通信(可靠RPC调用)保证严格保序。非可靠通信(属性同步和非可靠RPC调用)不要求严格保序,乱序包会被当做丢包处理,只保证最终的状态一致。
Gameplay类 同步设置
从Gameplay的层面来看, Actor上的bReplicates属性是同步的总开关。只有在bReplicates设置为true的情况下,Actor的属性复制,RPC,Component及子UObject的同步才会生效。
此外Actor上还有很多和同步相关的成员变量。从功能层面说,大致分为三类:
- 同步距离(NetCullDistance)
- 同步范围(AlwaysRelevant / OnlyRelevantToOwner)
- 同步频率(NetUpdateFrequency)
其中同步距离和同步范围会引出网络相关性的概念。 某个Actor对于某个客户端连接是可见的或者会影响到该客户端,则认为该Actor和该连接是网络相关的。服务器判断网络相关性的主要依据就是同步范围和同步距离。
- 如果同步范围是AlwaysRelevant,则同步给所有客户端连接。
- 如果同步范围是OnlyRelevantToOwner,则只同步给拥有它的客户端连接。
- 否则,则根据同步距离来界定可见性。
当某个Actor被界定为相关的,在某帧中是否会进行实际的同步仍然受到同步频率和优先级的限制。同步频率比较好理解,优先级的作用主要是在流量被限制的情况下,优先同步优先级高的Actor。优先级低的Actor,在达到流量限制的时候,会放到下一帧同步。
结语
UE4网络通信的第一篇就先介绍到这里。 下一篇介绍网络相关性。