目录
0 引言
RPC是UE进行网路同步的两种方式之一(复制、RPC)
官方文档
知乎文章:南京周润发
知乎文章1
1 RPC基本概念
1.1 定义
RPC (远程过程调用)是在本地调用但在其他机器(不同于执行调用的机器)上远程执行的函数。
RPC 函数非常有用,可允许客户端或服务器通过网络连接相互发送消息。变量复制是从服务器给客户端通信,单向的。
1.2 分类
UE中的RPC主要分为三种类型:服务器RPC、客户端RPC和多播RPC。每种类型的RPC都有其特定的用途和调用方式。
2 RPC的使用
三种RPC调用规则,官方文档的表格里面写的最清晰。
使用前确保开启了Actor复制的功能,这是使用网络通信功能的前提。
AMyCharacter::AMyCharacter()
{
bReplicates = true;
}
2.1 Client RPC
客户端RPC 用于从服务器向 特定客户端
发送请求。通常用于服务器通知客户端执行某些操作,例如更新UI、播放动画等。
定义
UFUNCTION(Client, Reliable)
void ClientFunction();
Client
:标识这是一个客户端RPC。Reliable
:标识这个RPC是可靠的,确保消息会被传递。
示例
MyCharacter.h
UFUNCTION(Client, Reliable)
void ClientDoSomething();
MyCharacter.cpp
void AMyCharacter::ClientDoSomething_Implementation()
{
// 客户端执行的逻辑
}
在服务器调用客户端RPC:
if (HasAuthority())
{
ClientDoSomething();
}
2.1.1 Client RPC是如何确定给哪个客户端通信的?
Client RPC是服务器调用RPC函数,然后特定的客户端执行这个函数。那么是如何知道是要哪个客户端执行呢?
通过PlayerController、PlayerState实现,因为在Gameplay中,这两个对象是客户端自己独有的。可以通过这个标识不同的客户端。
也就是说在PlayerController类中定义了一个Client RPC函数,然后我服务器上的PlayerControllerA对象执行这个RPC,只有PlayerControllerA对象主动端才会在客户端执行这个 Client RPC函数,其他客户端是不会执行的。
2.2 Server RPC
服务器RPC用于从客户端向服务器发送请求。通常用于客户端请求服务器执行某些操作,例如处理玩家输入、请求数据等。由于服务器就一个,所以就没有Client RPC那种问题。
注意:假如是客户端的PlayerController调用了一个Server RPC函数,此时只有服务器上对应的PlayerController才会执行这个Server RPC函数,而不是服务器上所有的PlayerController都会执行这个函数。
定义
UFUNCTION(Server, Reliable, WithValidation)
void ServerFunction();
Server
:标识这是一个服务器RPC。Reliable
:标识这个RPC是可靠的,确保消息会被传递。WithValidation
:标识这个RPC需要验证函数。
示例
MyCharacter.h
UFUNCTION(Server, Reliable, WithValidation)
void ServerDoSomething();
MyCharacter.cpp
void AMyCharacter::ServerDoSomething_Implementation()
{
// 服务器端执行的逻辑
}
bool AMyCharacter::ServerDoSomething_Validate()
{
// 验证逻辑(通常用于防止作弊)
return true;
}
在客户端调用服务器RPC:
if (IsLocallyControlled())
{
ServerDoSomething();
}
2.3 Multicast RPC
多播RPC用于从服务器向所有客户端发送请求。通常用于广播事件,例如游戏状态更新、全局通知等。
定义
UFUNCTION(NetMulticast, Reliable)
void MulticastFunction();
NetMulticast
:标识这是一个多播RPC。Reliable
:标识这个RPC是可靠的,确保消息会被传递。
示例
MyCharacter.h
UFUNCTION(NetMulticast, Reliable)
void MulticastDoSomething();
MyCharacter.cpp
void AMyCharacter::MulticastDoSomething_Implementation()
{
// 所有客户端执行的逻辑
}
在服务器调用多播RPC:
if (HasAuthority())
{
MulticastDoSomething();
}
2.4 RPC 的使用前提和作用范围
2.4.1 Client/Server RPC
- 使用前提:Client RPC 和 Server RPC 在调用和执行有一个前提,就是服务器和客户端都必须存在对应的实例才行。比如 GameMode 只存在于服务器,所以就无法调用 Client RPC 函数。在服务器上存在的对象,然后通过复制同步到客户端,此时服务器上和客户端就具有对应的实例,这个时候就可以使用RPC进行调用。
- 作用范围:假如在PlayerController类中写了一个 RPC 函数,客户端A上的 PlayerControllerA 调用了这个 Server RPC 函数,只有服务器上对应的 PlayerControllerA 实例才会执行这个 Server RPC函数, PlayerControllerB实例是不会执行这个函数的。同理 Client RPC 也是一样。
2.4.2 Multicast RPC
- 广播RPC(Multicast RPC):由服务器调用,并在所有客户端上的对应实例上执行。
- 使用前提:只能由服务器调用,所有客户端上的对应实例都会执行这个RPC函数。(所以PlayerController无法进行广播RPC,因为他在客户端是唯一的)
- 应用范围:适用于需要在所有客户端上同步某些状态或事件的情况。