Init
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# BlueprintAuthorityOnly
|
||||
|
||||
- **功能描述:** 这个函数只能在拥有网络权限的端上运行。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags中添加[FUNC_BlueprintAuthorityOnly](../../../../Flags/EFunctionFlags/FUNC_BlueprintAuthorityOnly.md)
|
||||
- **常用程度:** ★★★
|
||||
|
||||
这个函数只能在拥有网络权限的端上运行。HasAuthority::(GetLocalRole() == ROLE_Authority)。共有4种NetRole: ROLE_None(不复制),ROLE_SimulatedProxy(在客户端上模拟的代理),ROLE_AutonomousProxy(在客户端上的匿名代理,接收玩家输入),ROLE_Authority(服务器拥有权限的)。
|
||||
|
||||
因此BlueprintAuthorityOnly限定这个函数只能在服务器上运行,这个“服务器”可以是LS服务器,DS服务器,单机(可以看作没有客户端的服务器)。
|
||||
|
||||
注意在测试的时候需要把该Actor设置为Replicates。
|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_Network :public AActor
|
||||
{
|
||||
public:
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
//FunctionFlags: FUNC_Final | FUNC_Native | FUNC_Public | FUNC_BlueprintCallable
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void MyFunc_Default();
|
||||
|
||||
//FunctionFlags: FUNC_Final | FUNC_BlueprintAuthorityOnly | FUNC_Native | FUNC_Public | FUNC_BlueprintCallable
|
||||
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly)
|
||||
void MyFunc_BlueprintAuthorityOnly();
|
||||
|
||||
static void PrintFuncStatus(AActor* actor,FString funcName);
|
||||
};
|
||||
|
||||
void AMyFunction_Network::MyFunc_Default()
|
||||
{
|
||||
PrintFuncStatus(this,TEXT("MyFunc_Default"));
|
||||
}
|
||||
|
||||
void AMyFunction_Network::MyFunc_BlueprintAuthorityOnly()
|
||||
{
|
||||
PrintFuncStatus(this,TEXT("MyFunc_BlueprintAuthorityOnly"));
|
||||
}
|
||||
|
||||
void AMyFunction_Network::PrintFuncStatus(AActor* actor, FString funcName)
|
||||
{
|
||||
FString actorName = actor->GetName();
|
||||
|
||||
FString localRoleStr;
|
||||
UEnum::GetValueAsString(actor->GetLocalRole(), localRoleStr);
|
||||
|
||||
FString remoteRoleStr;
|
||||
UEnum::GetValueAsString(actor->GetRemoteRole(), remoteRoleStr);
|
||||
|
||||
FString netModeStr = Insider::NetModeToString(actor->GetNetMode());
|
||||
|
||||
FString str = FString::Printf(TEXT("%s\t%s\t%s\tLocal:%s\tRemote:%s"), *funcName,*actorName, *netModeStr, *localRoleStr, *remoteRoleStr);
|
||||
GEngine->AddOnScreenDebugMessage(-1, 20.f, FColor::Red, str);
|
||||
|
||||
UE_LOG(LogInsider, Display, TEXT("%s"), *str);
|
||||
}
|
||||
```
|
||||
|
||||
## 蓝图代码:
|
||||
|
||||

|
||||
|
||||
对于不Replicated的Actor:
|
||||
|
||||
```cpp
|
||||
MyFunc_Default BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_None
|
||||
MyFunc_Default BP_Network_C_1 NM_Client Local:ROLE_None Remote:ROLE_Authority
|
||||
MyFunc_Default BP_Network_C_1 NM_Client Local:ROLE_None Remote:ROLE_Authority
|
||||
```
|
||||
|
||||
而对于Replicated的Actor,同时有1个S和两个C,运行普通的函数:
|
||||
|
||||
```cpp
|
||||
MyFunc_Default BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
MyFunc_Default BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
MyFunc_Default BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
```
|
||||
|
||||
如果允许的BlueprintAuthorityOnly函数:
|
||||
|
||||
```cpp
|
||||
MyFunc_BlueprintAuthorityOnly BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
```
|
||||
|
||||
结果可见,Default的函数在3个端上都可以运行,而BlueprintAuthorityOnly只能在服务器上运行。而Client上无法运行。
|
||||
|
||||
## 原理:
|
||||
|
||||
```cpp
|
||||
int32 AActor::GetFunctionCallspace( UFunction* Function, FFrame* Stack )
|
||||
{
|
||||
FunctionCallspace::Type Callspace = (LocalRole < ROLE_Authority) && Function->HasAllFunctionFlags(FUNC_BlueprintAuthorityOnly) ? FunctionCallspace::Absorbed : FunctionCallspace::Local;
|
||||
}
|
||||
```
|
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/BlueprintAuthorityOnly/Untitled.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/BlueprintAuthorityOnly/Untitled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
# BlueprintCosmetic
|
||||
|
||||
- **功能描述:** 此函数为修饰性的,无法在DS上运行。
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags中加入[FUNC_BlueprintCosmetic](../../../../Flags/EFunctionFlags/FUNC_BlueprintCosmetic.md)
|
||||
- **常用程度:** ★★★
|
||||
|
||||
这个函数是修饰性的,所谓修饰性是指这个函数的内容是为了展现一些与逻辑无关的内容,比如动画音效特效等。因为DS并没有实际的画面输出,因此这些修饰性的函数是对DS无意义的。因此这些修饰性函数会被无视掉。
|
||||
|
||||
但是也注意在ListenServer或Client上,这二者都会允许运行。因为这两个端都需要画面展示。
|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UFUNCTION(BlueprintCallable, BlueprintCosmetic)
|
||||
void MyFunc_BlueprintCosmetic();
|
||||
```
|
||||
|
||||
## 测试蓝图:
|
||||
|
||||
节点上的电脑标记就是意味着只在客户端上运行。
|
||||
|
||||

|
||||
|
||||
结果输出
|
||||
|
||||
```cpp
|
||||
MyFunc_BlueprintCosmetic BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
MyFunc_BlueprintCosmetic BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
MyFunc_BlueprintCosmetic BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
```
|
||||
|
||||
## 原理:
|
||||
|
||||
```cpp
|
||||
int32 AActor::GetFunctionCallspace( UFunction* Function, FFrame* Stack )
|
||||
{
|
||||
// Dedicated servers don't care about "cosmetic" functions.
|
||||
if (NetMode == NM_DedicatedServer && Function->HasAllFunctionFlags(FUNC_BlueprintCosmetic))
|
||||
{
|
||||
DEBUG_CALLSPACE(TEXT("GetFunctionCallspace Blueprint Cosmetic Absorbed: %s"), *Function->GetName());
|
||||
return FunctionCallspace::Absorbed;
|
||||
}
|
||||
}
|
||||
```
|
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/BlueprintCosmetic/Untitled.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/BlueprintCosmetic/Untitled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
# Client
|
||||
|
||||
- **功能描述:** 在Client-owned的Actor上(PlayerController或Pawn)执行一个RPC函数,只运行在客户端上。对应的实现函数会添加_Implementation后缀。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags加入[FUNC_Net](../../../../Flags/EFunctionFlags/FUNC_Net.md)、[FUNC_NetClient](../../../../Flags/EFunctionFlags/FUNC_NetClient.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
在Client-owned的Actor上(PlayerController或Pawn)执行一个RPC函数,只运行在客户端上。对应的实现函数会添加_Implementation后缀。
|
||||
|
||||
一般用于从Server发送一个RPC到Client。和蓝图里RunOnClient的效果一样。
|
||||
|
||||
所谓Client-owned,参考文档:[https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/](https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/)
|
||||
|
||||

|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_PlayerController :public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Client, Reliable)
|
||||
void MyFunc_RunOnClient();
|
||||
};
|
||||
|
||||
void AMyFunction_PlayerController::MyFunc_RunOnClient_Implementation()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc_RunOnClient_Implementation"));
|
||||
}
|
||||
```
|
||||
|
||||
测试蓝图:PIE模式,一个ListenServer+2Client
|
||||
|
||||

|
||||
|
||||
## 测试输出结果:
|
||||
|
||||
```cpp
|
||||
MyFunc_Client_Implementation BP_NetworkPC_C_0 NM_Client Local:ROLE_AutonomousProxy Remote:ROLE_Authority
|
||||
OtherClientFunc BP_NetworkPC_C_0 NM_Client Local:ROLE_AutonomousProxy Remote:ROLE_Authority
|
||||
```
|
||||
|
||||
可见,测试代码中取第2个PC,发出一个Run on Client的RPC调用,最终在Client上成功触发。C++定义的函数和蓝图中添加的自定义RunOnClient事件效果是等价的。
|
||||
|
||||
而如果这个函数在Server owned Actor上执行,则只会在运行在服务器上,不会传递到客户端。
|
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Client/Untitled 1.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Client/Untitled 1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Client/Untitled.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Client/Untitled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
# NetMulticast
|
||||
|
||||
- **功能描述:** 定义一个多播RPC函数在服务器和客户端上都执行。对应的实现函数会添加_Implementation后缀。
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags中加入[FUNC_Net](../../../../Flags/EFunctionFlags/FUNC_Net.md)、[FUNC_NetMulticast](../../../../Flags/EFunctionFlags/FUNC_NetMulticast.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
定义一个多播RPC函数在服务器和客户端上都执行。对应的实现函数会添加_Implementation后缀。
|
||||
|
||||
RPC执行的规则,参考文档:[https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/](https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/)
|
||||
|
||||

|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_Network :public AActor
|
||||
{
|
||||
public:
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, NetMulticast, Reliable)
|
||||
void MyFunc_NetMulticast();
|
||||
};
|
||||
|
||||
void AMyFunction_Network::MyFunc_NetMulticast_Implementation()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc_NetMulticast_Implementation"));
|
||||
}
|
||||
```
|
||||
|
||||
测试蓝图:PIE模式,一个ListenServer+2Client
|
||||
|
||||

|
||||
|
||||
## 测试输出结果:
|
||||
|
||||
```cpp
|
||||
LogInsider: Display: 46715a00 MyFunc_NetMulticast_Implementation BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
LogInsider: Display: 46e65000 MyFunc_NetMulticast_Implementation BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 29aaaa00 MyFunc_NetMulticast_Implementation BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
|
||||
LogInsider: Display: 4ff44600 OtherMulticastFunc BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
LogInsider: Display: 3bf89b00 OtherMulticastFunc BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 29d68700 OtherMulticastFunc BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
```
|
||||
|
||||
在一个Server Owned的Actor上,发出Multicast RPC事件调用,可以见到在3个端都得到了调用。
|
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/NetMulticast/Untitled.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/NetMulticast/Untitled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
# Reliable
|
||||
|
||||
- **功能描述:** 指定一个RPC函数为“可靠的”,当遇见网络错误时会重发以保证到达。一般用在逻辑关键的函数上。
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags加入[FUNC_NetReliable](../../../Flags/EFunctionFlags/FUNC_NetReliable.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
指定一个RPC函数为“可靠的”,当遇见网络错误时会重发以保证到达。一般用在逻辑关键的函数上。
|
||||
|
||||
具体的原理涉及到了重发信息包的逻辑。
|
@@ -0,0 +1,52 @@
|
||||
# Server
|
||||
|
||||
- **功能描述:** 在Client-owned的Actor上(PlayerController或Pawn)执行一个RPC函数,只运行在服务器上。对应的实现函数会添加_Implementation后缀
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags中加入[FUNC_Net](../../../../Flags/EFunctionFlags/FUNC_Net.md)、[FUNC_NetServer](../../../../Flags/EFunctionFlags/FUNC_NetServer.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
在Client-owned的Actor上(PlayerController或Pawn)执行一个RPC函数,只运行在服务器上。对应的实现函数会添加_Implementation后缀。
|
||||
|
||||
和RunOnServer的效果一样。
|
||||
|
||||
所谓Client-owned,参考文档:[https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/](https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/)
|
||||
|
||||

|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_PlayerController :public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Server, Reliable)
|
||||
void MyFunc_RunOnServer();
|
||||
};
|
||||
|
||||
void AMyFunction_PlayerController::MyFunc_RunOnServer_Implementation()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc_RunOnServer_Implementation"));
|
||||
}
|
||||
```
|
||||
|
||||
测试蓝图:PIE模式,一个ListenServer+2Client
|
||||
|
||||

|
||||
|
||||
## 测试输出结果:
|
||||
|
||||
```cpp
|
||||
LogInsider: Display: 5118b400 MyFunc_RunOnServer_Implementation BP_NetworkPC_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
LogInsider: Display: 44ec3c00 MyFunc_RunOnServer_Implementation BP_NetworkPC_C_2 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
|
||||
LogInsider: Display: 49999000 OtherServerFunc BP_NetworkPC_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
LogInsider: Display: 4bcbd800 OtherServerFunc BP_NetworkPC_C_2 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
```
|
||||
|
||||
可见,测试代码中取第2个PC,发出一个Run on Server的RPC调用,最终在Server上成功触发。C++定义的函数和蓝图中添加的自定义RunOnServer事件效果是等价的。
|
||||
|
||||
而如果这个函数在Server owned Actor上执行,则只会在运行在服务器上,不会传递到客户端。
|
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Server/Untitled.png
(Stored with Git LFS)
Normal file
BIN
03-UnrealEngine/Gameplay/UObject/UnrealSpecifiers/Specifier/UFUNCTION/Network/Server/Untitled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -0,0 +1,39 @@
|
||||
# ServiceRequest
|
||||
|
||||
- **功能描述:** 此函数为RPC(远程过程调用)服务请求。rpc服务请求
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在Meta中加入[CustomThunk](../../../Meta/UHT/CustomThunk.md),在FunctionFlags加入[FUNC_Net](../../../Flags/EFunctionFlags/FUNC_Net.md)、[FUNC_Event](../../../Flags/EFunctionFlags/FUNC_Event.md)、[FUNC_NetReliable](../../../Flags/EFunctionFlags/FUNC_NetReliable.md)、[FUNC_NetRequest](../../../Flags/EFunctionFlags/FUNC_NetRequest.md)
|
||||
|
||||
在源码里都没看到使用,只搜到
|
||||
|
||||
```cpp
|
||||
UCLASS()
|
||||
class UTestReplicationStateDescriptor_TestFunctionWithNotReplicatedNonPODParameters : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
// Currently some features such as not replicating all parameters isn't allowed on regular RPCs
|
||||
UFUNCTION(ServiceRequest(Iris))
|
||||
void FunctionWithNotReplicatedNonPODParameters(int Param0, bool Param1, int Param2, UPARAM(NotReplicated) const TArray<FTestReplicationStateDescriptor_TestStructWithRefCArray>& NotReplicatedParam3);
|
||||
void FunctionWithNotReplicatedNonPODParameters_Implementation(int Param0, bool Param1, int Param2, UPARAM(NotReplicated) const TArray<FTestReplicationStateDescriptor_TestStructWithRefCArray>& NotReplicatedParam3);
|
||||
};
|
||||
```
|
||||
|
||||
## UDN回答:
|
||||
|
||||
Alex: Those specifiers were added quite a while ago as a way to mark functions as RPC requests/responses to and from a backend service, the name of which would be given as part of the specifier: UFUNCTION(ServiceRequest(<Endpoint Name>)). However, the feature was never fully implemented, and since then the specifiers have only been used internally (and even then, I don't believe "ServiceResponse" is used at all anymore). This is why there isn't any public documentation or examples available, as they're not formally supported in the engine. You can check out ServiceRequestSpecifier and ServiceResponseSpecifier in UhtFunctionSpecifiers.cs to see how UHT handles these specifiers.
|
||||
|
||||
Mi: 这两个标记是我们用来自由扩展和自己的服务器通信的(例如http request),譬如可以提供自己的NetDriver处理特定标记的ServiceRequest的RPC,自己序列化对应参数发给自己的服务。
|
||||
|
||||
“意思是如果使用引擎的默认实现的话,使用这两个标记是无效的吗?我尝试在服务器或者客户端发起对ServiceRequest标记的ufunction的调用,结果都是会打印错误日志”
|
||||
|
||||
是的,默认的UE client和DS通信的NetDriver的RPC不需要这两个关键字,用了之后会找不到相应处理的NetDriver的实现。
|
||||
|
||||
在Server Owned Actor上调用会出错:LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_Network_C_1. Function MyFunc_ServiceRequest will not be processed.
|
||||
|
||||
在PC上Server调用也会:
|
||||
|
||||
LogRep: Error: Rejected RPC function due to access rights. Object: BP_NetworkPC_C /Game/UEDPIE_0_StartMap.StartMap:PersistentLevel.BP_NetworkPC_C_1, Function: MyFunc_ServiceRequest
|
||||
LogNet: Error: UActorChannel::ProcessBunch: Replicator.ReceivedBunch failed. Closing connection. RepObj: BP_NetworkPC_C /Game/UEDPIE_0_StartMap.StartMap:PersistentLevel.BP_NetworkPC_C_1, Channel: 3
|
@@ -0,0 +1,9 @@
|
||||
# ServiceResponse
|
||||
|
||||
- **功能描述:** 此函数为RPC服务响应。rpc服务回复
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags加入[FUNC_Net](../../../Flags/EFunctionFlags/FUNC_Net.md)、[FUNC_Event](../../../Flags/EFunctionFlags/FUNC_Event.md)、[FUNC_NetReliable](../../../Flags/EFunctionFlags/FUNC_NetReliable.md)、[FUNC_NetResponse](../../../Flags/EFunctionFlags/FUNC_NetResponse.md)
|
||||
|
||||
在源码里一个也没看到使用。
|
@@ -0,0 +1,9 @@
|
||||
# Unreliable
|
||||
|
||||
- **功能描述:** 指定一个RPC函数为“不可靠的”,当遇见网络错误时就会被丢弃。一般用在传播效果表现的函数上,就算漏掉也没有关系。
|
||||
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
指定一个RPC函数为“不可靠的”,当遇见网络错误时就会被丢弃。一般用在传播效果表现的函数上,就算漏掉也没有关系。
|
@@ -0,0 +1,118 @@
|
||||
# WithValidation
|
||||
|
||||
- **功能描述:** 指定一个RPC函数在执行前需要验证,只有验证通过才可以执行。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** Network
|
||||
- **作用机制:** 在FunctionFlags中加入[FUNC_NetValidate](../../../Flags/EFunctionFlags/FUNC_NetValidate.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
指定一个RPC函数在执行前需要验证,只有验证通过才可以执行。
|
||||
|
||||
WithValidation实际上可以用于Client,Server,NetMulticast的RPC函数,但一般来说还是用在Server的最多,因为一般是Server的数据最权威可以进行数据合法性校验。
|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_PlayerController :public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Client, Reliable,WithValidation)
|
||||
void MyFunc2_RunOnClient();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Server, Reliable,WithValidation)
|
||||
void MyFunc2_RunOnServer();
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API AMyFunction_Network :public AActor
|
||||
{
|
||||
public:
|
||||
GENERATED_BODY()
|
||||
UFUNCTION(BlueprintCallable, NetMulticast, Reliable,WithValidation)
|
||||
void MyFunc2_NetMulticast();
|
||||
};
|
||||
|
||||
void AMyFunction_PlayerController::MyFunc2_RunOnServer_Implementation()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc2_RunOnServer_Implementation"));
|
||||
}
|
||||
|
||||
bool AMyFunction_PlayerController::MyFunc2_RunOnServer_Validate()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc2_RunOnServer_Validate"));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AMyFunction_Network::MyFunc2_NetMulticast_Validate()
|
||||
{
|
||||
UInsiderLibrary::PrintFuncStatus(this, TEXT("MyFunc2_NetMulticast_Validate"));
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## 测试结果:
|
||||
|
||||
```cpp
|
||||
RunOnClient:
|
||||
LogInsider: Display: 815f7800 MyFunc2_RunOnClient_Validate BP_NetworkPC_C_0 NM_Client Local:ROLE_AutonomousProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 815f7800 MyFunc2_RunOnClient_Implementation BP_NetworkPC_C_0 NM_Client Local:ROLE_AutonomousProxy Remote:ROLE_Authority
|
||||
|
||||
RunOnServer:
|
||||
LogInsider: Display: 7fd11800 MyFunc2_RunOnServer_Validate BP_NetworkPC_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
LogInsider: Display: 7fd11800 MyFunc2_RunOnServer_Implementation BP_NetworkPC_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_AutonomousProxy
|
||||
|
||||
Multicast: ServerOwned
|
||||
LogInsider: Display: 947e6400 MyFunc2_NetMulticast_Validate BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
LogInsider: Display: 947e6400 MyFunc2_NetMulticast_Implementation BP_Network_C_1 NM_ListenServer Local:ROLE_Authority Remote:ROLE_SimulatedProxy
|
||||
LogInsider: Display: 8795eb00 MyFunc2_NetMulticast_Validate BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 8795eb00 MyFunc2_NetMulticast_Implementation BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 8f6a3700 MyFunc2_NetMulticast_Validate BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
LogInsider: Display: 8f6a3700 MyFunc2_NetMulticast_Implementation BP_Network_C_1 NM_Client Local:ROLE_SimulatedProxy Remote:ROLE_Authority
|
||||
|
||||
```
|
||||
|
||||
## 原理:
|
||||
|
||||
如果加上WithValidation标记,在UHT生成代码的时候就会:
|
||||
|
||||
```cpp
|
||||
DEFINE_FUNCTION(AMyFunction_PlayerController::execMyFunc2_RunOnServer)
|
||||
{
|
||||
P_FINISH;
|
||||
P_NATIVE_BEGIN;
|
||||
if (!P_THIS->MyFunc2_RunOnServer_Validate())
|
||||
{
|
||||
RPC_ValidateFailed(TEXT("MyFunc2_RunOnServer_Validate"));
|
||||
return;
|
||||
}
|
||||
P_THIS->MyFunc2_RunOnServer_Implementation();
|
||||
P_NATIVE_END;
|
||||
}
|
||||
DEFINE_FUNCTION(AMyFunction_PlayerController::execMyFunc2_RunOnClient)
|
||||
{
|
||||
P_FINISH;
|
||||
P_NATIVE_BEGIN;
|
||||
if (!P_THIS->MyFunc2_RunOnClient_Validate())
|
||||
{
|
||||
RPC_ValidateFailed(TEXT("MyFunc2_RunOnClient_Validate"));
|
||||
return;
|
||||
}
|
||||
P_THIS->MyFunc2_RunOnClient_Implementation();
|
||||
P_NATIVE_END;
|
||||
}
|
||||
|
||||
DEFINE_FUNCTION(AMyFunction_Network::execMyFunc2_NetMulticast)
|
||||
{
|
||||
P_FINISH;
|
||||
P_NATIVE_BEGIN;
|
||||
if (!P_THIS->MyFunc2_NetMulticast_Validate())
|
||||
{
|
||||
RPC_ValidateFailed(TEXT("MyFunc2_NetMulticast_Validate"));
|
||||
return;
|
||||
}
|
||||
P_THIS->MyFunc2_NetMulticast_Implementation();
|
||||
P_NATIVE_END;
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user