联网和多人游戏
客户端和服务器同步数据和调用程序的过程被称为复制(Replication)
虚幻引擎使用 客户端-服务器 模型。网络中的一台计算机作为 服务器 主持多人游戏会话,而所有其他玩家的计算机作为 客户端 连接到该服务器。然后,服务器与连接的客户端分享游戏状态信息,并提供一种客户端之间通信的方法。
复制是指在网络会话中的不同机器间复制游戏状态信息。若正确设置复制,将可同步不同机器的游戏实例。多数Actor默认不会启用复制,且将本地执行所有功能。
在C++ Actor类中设置 bReplicates 变量,或将Actor蓝图的 复制(Replicates) 设置设为 true,可启用给定类的Actor复制。
Actor的复制
Actor主要通过两种方式更新:1、属性更新 2、RPC(远程过程调用)
属性更新和RPC的主要区别:属性在发生变化时自动更新,RPC只能在被执行时获得调用更新
组件复制
静态组件:随Actor一起创建的静态组件。无需通过复制存在于客户端
动态组件:运行时服务器上生成的组件。需通过复制的方式存在于所有客户端
可以将变量设置成Replicated,也就是说,这个变量会生成一个该变量的一对一副本,然后该副本将从服务器复制到客户端。或者你可以使用RepNotify变量。
它拥有Replicated的所有功能,同时还提供了一个函数,每当该函数关联的变量更新时,该函数就会调用并在服务器和客户端上执行。
Actor的Role和RemoteRole属性
如果 Role 是 ROLE_Authority
RemoteRole 是 ROLE_SimulatedProxy 或 ROLE_AutonomousProxy,就说明这个引擎实例负责将此 actor 复制到远程连接。
RPC:
RPC(远程过程调用)是在本地调用但在其他机器(不同于执行调用的机器)上远程执行的函数,可允许客户端和服务器通过网络连接相互发送消息
要将一个函数声明为RPC,只需将Server、Client、NetMulticast关键字添加到UFUNCTION声明
1、声明一个服务器上调用、客户端执行的RPC:
UFUNCTION( Client )
void ClientRPCFunction();
2、声明一个客户端上调用、服务器执行的RPC:
UFUNCTION( Server )void ServerRPCFunction();
3、多播 RPC 可以从服务器调用,然后在服务器和当前连接的所有客户端上执行
UFUNCTION( NetMulticast )void MulticastRPCFunction();
注意:客户端调用只能在本地执行
4、默认情况,RPC并不可靠。要确保调用需要指定Reliable关键字
UFUNCTION( Client, Reliable )void ClientRPCFunction();
多人游戏下的Gameplay框架:
GameInstance在引擎会话的持续时间内一直存在,意味着在引擎启动时创建,并在引擎关闭后才会销毁或更换。服务器和每个客户端上都存在一个独立的GameInstance,这些实例彼此不通信。由于GameInstance存在于游戏会话之外,并且是在关卡加载期间唯一存在的游戏结构体,因此非常适合于保存特定类型的持久数据
GameMode对象仅存在于服务器上。它通常存储客户端不需要明确知道的游戏信息。
GameState存在于服务器和客户端上,因此服务器可以在GameState上使用复制变量让所有客户端保持最新的游戏数据。
每一台客户端上的每一个玩家存在一个PlayerController。它们在服务器和关联的客户机之间进行复制,但不会复制到其他客户端,因此在服务器上每个玩家都有PlayerController,但本地客户端只有本地玩家的PlayerController。
服务器和客户端上存在与游戏相连的每个玩家的PlayerState。这个类可以用于所有客户端感兴趣的复制属性,而不仅仅是所属客户端,如单个玩家在自由竞赛游戏中的当前分数。
Pawn(包括Character)也存在于服务器和所有客户端上,可以包含复制变量和事件。决定对特定变量或事件使用PlayerController、PlayerState还是Pawn取决于具体情况,但务必要记住的是,只要所属玩家保持与游戏相连,且游戏没有加载新关卡,则PlayerController和PlayerState就保持不变,而`Pawn`则不然。例如,如果Pawn在游戏期间死亡,它通常会被销毁并替换为一个新Pawn,而PlayerController和PlayerState将持续存在,并在新Pawn产生后与新Pawn关联。