RPC
- Local 단위에서 호출하여 Remote로 연결된 1개 이상의 Machinge에서 실행되는 함수
- Return이 없는 단방향 함수 호출이 특징
- RPC는 주로 일시적이거나, 외형적으로 드러나는 Unreliable Gameplay Event에 사용된다.
- 사운드 재생
- Particle 생성
- Animation 재생
- RPC는 Replicated/ReplicatedUsing 선언이 된 Property의 Replication을 보완하는 중요한 기능이다.
- RPC를 호출하려면 다음 2가지 조건이 성립되어야 한다.
- Actor나 Actor Component일 것.
- RPC를 호출하는 Object가 Replicate되어 있을 것.
- 마지막으로 RPC를 잘 사용하기 위해서는 Ownership을 잘 이해하는 편이 좋다.
Type
Client
- 이 Actor에 대해 Client Connection을 소유한 Client에서 실행되는 Unicast RPC
#pragma once
#include "DerivedActor.generated.h"
UCLASS()
class ADerivedActor : public AActor
{
GENERATED_BODY()
public:
// Client RPC Function
UFUNCTION(Client)
void ClientRPC();
}
#include "DerivedActor.h"
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
bReplicates = true;
}
void ADerivedActor::ClientRPC_Implementation()
{
// This log will print on every machine that executes this function.
UE_LOG(LogTemp, Log, TEXT("ClientRPC executed."))
}
// Call from client to run on server
ADerivedClientActor* MyDerivedClientActor;
MyDerivedClientActor->ClientRPC();
Execution Matrix
Server
- 해당 Actor를 소유하는 Client에서 호출하여 Server에서 실행되는 Unicast RPC
#pragma once
#include "DerivedActor.generated.h"
UCLASS()
class ADerivedActor : public AActor
{
GENERATED_BODY()
public:
// Server RPC Function
UFUNCTION(Server)
void ServerRPC();
}
#include "DerivedActor.h"
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
bReplicates = true;
}
void ADerivedActor::ServerRPC_Implementation()
{
// This function only executes if ServerRPC_Validate returns true.
// This log will print on every machine that executes this function.
UE_LOG(LogTemp, Log, TEXT("ServerRPC executed."))
}
// Call from client to run on server
ADerivedClientActor* MyDerivedClientActor;
MyDerivedClientActor->ServerRPC();
Execution Matrix
WithValidation
- Server RPC에서만 사용할 수 있는 Specifier
- Server RPC의 신뢰성과 Network Policy를 구현할 수 있다.
#pragma once
#include "DerivedActor.generated.h"
UCLASS()
class ADerivedActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(Replicated)
int32 Health;
int32 MAXHEALTH = 100;
// Server Unreliable RPC Function
UFUNCTION(Server, Unreliable, WithValidation)
void ServerUnreliableRPC(int32 RecoverHealth);
}
- Validate 함수는 내부 로직을 통해 RPC 함수를 Server에서 실행할지 여부를 판단한다.
- 그렇기에 Validate Specifier가 선언된 Server RPC가 실행될 때 Validate 함수가 가장 먼저 호출된다.
#include "DerivedActor.h"
// RPC Validation Implementation
bool ServerUnreliableRPC_Validate(int32 RecoverHealth)
{
if (Health + RecoverHealth > MAXHEALTH)
{
return false;
}
return true;
}
// RPC Implementation
void ServerUnreliableRPC_Implementation(int32 RecoverHealth)
{
Health += RecoverHealth;
}
- 만약 Validate 함수에서 false를 반환하면, 해당 Server RPC를 전송한 Client는 Server로부터 연결이 끊긴다.
NetMulticast
- Server에서 호출
- 호출한 Actor와 Relevant한 모든 Client에서 실행되는 Multicast RPC
- Client에서도 호출할 수 있으나 Local에서만 동작한다.
#pragma once
#include "DerivedActor.generated.h"
UCLASS()
class ADerivedActor : public AActor
{
GENERATED_BODY()
public:
// Multicast RPC Function
UFUNCTION(NetMulticast)
void MulticastRPC();
}
#include "DerivedActor.h"
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
bReplicates = true;
}
void ADerivedActor::MulticastRPC_Implementation()
{
// This log will print on every machine that executes this function.
UE_LOG(LogTemp, Log, TEXT("MulticastRPC executed."))
}
// Call from server to run on server and all relevant clients
ADerviedServerActor* MyDerivedServerActor;
MyDerievedServerActor->MulticastRPC();
Execution Matrix
Reliability
- Client/Server/NetMulticast와 같이 사용되는 Specifier
Reliable
- RPC 수신자로부터 ACK를 받지 못하면 RPC를 재전송한다.
- 다음 RPC 호출은 앞선 RPC의 ACK를 수신할 때 실행된다.
- 순서대로 도착하는 것을 보장해준다.
Unreliable
- RPC Packet이 Drop되면 실행되지 않는다.
- 도착 순서를 보장하지 않는다.
Send Policy
- ERemoteFunctionSendPolicy를 지정하여 RPC의 전송 순서를 명시적으로 조정할 수 있다.
enum class ERemoteFunctionSendPolicy
{
/** Unreliable multicast are queued. Everything else is send immediately */
Default,
/** Bunch is send immediately no matter what */
ForceSend,
/** Bunch is queued until next actor replication, no matter what */
ForceQueue,
};
- Send Policy 조절은 NetDriver::ProcessRemoteFunctionForChannel을 통해 가능하다.
/** Process a remote function on given actor channel. This is called by ::ProcessRemoteFunction.*/
ENGINE_API void ProcessRemoteFunctionForChannel(
UActorChannel* Ch,
const class FClassNetCache* ClassCache,
const FFieldNetCache* FieldCache,
UObject* TargetObj,
UNetConnection* Connection,
UFunction* Function,
void* Parms,
FOutParmRec* OutParms,
FFrame* Stack,
const bool IsServer,
const ERemoteFunctionSendPolicy SendPolicy = ERemoteFunctionSendPolicy::Default);
void UNetDriver::ProcessRemoteFunctionForChannel(
UActorChannel* Ch,
const FClassNetCache* ClassCache,
const FFieldNetCache* FieldCache,
UObject* TargetObj,
UNetConnection* Connection,
UFunction* Function,
void* Parms,
FOutParmRec* OutParms,
FFrame* Stack,
const bool bIsServer,
const ERemoteFunctionSendPolicy SendPolicy)
{
EProcessRemoteFunctionFlags UnusedFlags = EProcessRemoteFunctionFlags::None;
ProcessRemoteFunctionForChannelPrivate(Ch, ClassCache, FieldCache, TargetObj, Connection, Function, Parms, OutParms, Stack, bIsServer, SendPolicy, UnusedFlags);
}
Default
- RPC가 bunch에 직렬화 된다.
- Bunch는 다음 Frame 마지막에 NetUpdate에서 전송된다.
ForceSend
- RPC가 NetDriver::PostTickDispatch에서 trigger되면 bunch에 즉시 직렬화 되고 Network에 전송된다.
- tick의 나머지 부분이 동작하는 도중에 trigger 되면, Default로 동작한다.
- 이 특별한 RPC 최적화 기법은 아래 조건 하에서 동작한다.
- Replication Graph나 Iris를 사용할 때에만 동작한다.
- NetWroldTickTime에서 호출된 RPC에서 동작.
- 수신한 패킷되고 수신한 RPC가 실행된다.
ForceQueue
- Network Update이 마무리 될 때 Bandwidth가 남아 있다면 Bunch에 직렬화된다.
'UE5 > Network' 카테고리의 다른 글
[Network] Replication Execution Order (0) | 2024.06.28 |
---|---|
[Network] Property Replication (1) | 2024.06.28 |
[Network] Network Property (0) | 2024.06.25 |
[Network] Network Driver (0) | 2024.06.18 |
[Network] DemoNetDriver 및 Streamer (0) | 2024.06.17 |