[Unreal Engine] Remote Procedure Calls (RPC)

Imeamangryang·2025년 7월 29일
post-thumbnail

출처 ㅣ Cedric Neukirchen - Multiplayer Network Compendium


Remote Procedure Calls

다른 복제(Replication) 방법으로는 "RPC"가 있습니다. RPC는 "Remote Procedure Call(원격 프로시저 호출)"의 약자입니다.

RPC는 다른 인스턴스에서 무언가를 호출할 때 사용됩니다. TV 리모컨이 TV에 신호를 보내는 것과 비슷합니다.

Unreal Engine에서는 클라이언트에서 서버로, 서버에서 클라이언트로, 또는 서버에서 특정 그룹으로 이벤트를 보내는 데 RPC를 사용합니다.

이러한 RPC는 반환값을 가질 수 없습니다! 값을 반환하려면 반대 방향으로 두 번째 RPC를 사용해야 합니다.

RPC는 특정 규칙 하에서만 동작합니다. 공식 문서에서도 확인할 수 있는 이 표에 그 규칙이 나와 있습니다:

  • Run on Server - 이 액터의 서버 인스턴스에서 실행됩니다.
  • Run on owning Client - 이 액터의 소유자 클라이언트에서 실행됩니다.
  • NetMulticast - 이 액터의 모든 인스턴스에서 실행됩니다.

RPC의 요구 사항 및 주의 사항

RPC가 완전히 동작하려면 몇 가지 요구 사항을 충족해야 합니다:

  1. RPC는 액터(Actor) 또는 복제되는 서브오브젝트(예: 컴포넌트)에서 호출되어야 합니다.
  2. 해당 액터(및 컴포넌트)는 복제되어야 합니다.
  3. 서버가 클라이언트에서 실행되도록 RPC를 호출하는 경우, 해당 액터를 소유한 클라이언트만 해당 함수를 실행합니다.
  4. 클라이언트가 서버에서 실행되도록 RPC를 호출하는 경우, 해당 클라이언트는 RPC가 호출되는 액터를 소유해야 합니다.
  5. 멀티캐스트(Multicast) RPC는 예외입니다:
    • 서버에서 호출하면, 서버는 로컬에서 실행하고, 해당 액터의 인스턴스가 관련된 모든 현재 연결된 클라이언트에서도 실행됩니다.
    • 클라이언트에서 호출하면, 멀티캐스트는 로컬에서만 실행되고, 서버나 다른 클라이언트에서는 실행되지 않습니다.
    • 현재 멀티캐스트 이벤트에 대해 간단한 트래픽 제한(throttling) 메커니즘이 적용됩니다:
      • 하나의 액터의 네트워크 업데이트 주기 동안 멀티캐스트 함수는 두 번 이상 복제되지 않습니다.
        장기적으로 Epic은 이 부분을 개선할 예정입니다.

서버에서 호출된 RPC

액터 소유권Not ReplicatedNetMulticastServerClient
Client-owned Actor서버에서 실행서버 및 모든 클라이언트에서 실행서버에서 실행액터의 소유 클라이언트에서 실행
Server-owned Actor서버에서 실행서버 및 모든 클라이언트에서 실행서버에서 실행서버에서 실행
Unonwed Actor서버에서 실행서버 및 모든 클라이언트에서 실행서버에서 실행서버에서 실행

클라이언트에서 호출된 RPC

액터 소유권복제되지 않음NetMulticast서버클라이언트
Owned by invoking Client호출한 클라이언트에서 실행호출한 클라이언트에서 실행서버에서 실행호출한 클라이언트에서 실행
Owned by a different Client호출한 클라이언트에서 실행호출한 클라이언트에서 실행무시됨호출한 클라이언트에서 실행
Server-owned Actor호출한 클라이언트에서 실행호출한 클라이언트에서 실행무시됨호출한 클라이언트에서 실행
Unowned Actor호출한 클라이언트에서 실행호출한 클라이언트에서 실행무시됨호출한 클라이언트에서 실행

블루프린트에서의 RPCs

블루프린트에서 RPC는 CustomEvent를 생성하고 Replicate로 설정하여 만듭니다.

RPC는 반환값을 가질 수 없으므로, 함수로는 만들 수 없습니다.

'Reliable' 체크박스를 사용하면 RPC를 '신뢰'하도록 설정하며, 해당 RPC가 손실되지 않도록 보장합니다.

🔥 주의
모든 RPC를 Reliable로 표시하지 마세요!
가끔 호출되고 반드시 도착해야 하는 RPC에만 사용해야 합니다.
Tick에서 Reliable RPC를 호출하면 Reliable 버퍼가 가득 차서, 다른 속성이나 RPC가 더 이상 처리되지 않을 수 있습니다.

C++에서의 RPCs

C++에서 네트워크 기능을 사용하려면 프로젝트 헤더에 “UnrealNetwork.h”를 포함해야 합니다. C++에서 RPC를 만드는 것은 비교적 간단하며, UFUNCTION() 매크로에 지정자를 추가하면 됩니다.

// 이것은 ServerRPC로, unreliable 및 WithValidation(필수!)로 표시됩니다.
UFUNCTION(Server, unreliable, WithValidation)
void Server_Interact();

CPP 파일에서는 '_Implementation' 접미사가 붙은 별도의 함수를 구현해야 합니다.

// 실제 구현 함수입니다. 호출할 때는 "Server_Interact"를 사용합니다.
void ATestPlayerCharacter::Server_Interact_Implementation()
{
    // 예: 문과 상호작용!
}

CPP 파일에는 '_Validate' 접미사가 붙은 버전도 필요합니다. 이에 대해서는 나중에 더 설명합니다.

bool ATestPlayerCharacter::Server_Interact_Validate()
{
    return true;
}

다른 두 가지 유형의 RPC는 다음과 같이 생성합니다:

ClientRPC는 'reliable' 또는 'unreliable'로 표시해야 합니다.

UFUNCTION(Client, unreliable)
void ClientRPCFunction();

Multicast RPC도 'reliable' 또는 'unreliable'로 표시해야 합니다.

UFUNCTION(NetMulticast, unreliable)
void MulticastRPCFunction();

물론, RPC에 'reliable' 키워드를 추가하여 신뢰성을 높일 수도 있습니다.

UFUNCTION(Client, reliable)
void ReliableClientRPCFunction();

UFUNCTION(NetMulticast, reliable)
void ReliableMulticastRPCFunction();

Validation (UE C++)

Validation의 개념은 RPC의 validation 함수가 파라미터에 문제가 있음을 감지하면, 해당 RPC 호출을 시작한 클라이언트/서버의 연결을 끊도록 시스템에 알릴 수 있다는 것입니다.

현재 모든 ServerRPCFunction에는 Validation이 필요합니다.
UFUNCTION 매크로의 'WithValidation' 키워드를 사용합니다.

UFUNCTION(Server, unreliable, WithValidation)
void SomeRPCFunction(int32 AddHealth);

'_Validate' 함수가 어떻게 사용되는지 예시는 다음과 같습니다:

bool ATestPlayerCharacter::SomeRPCFunction_Validate(int32 AddHealth)
{
    if (AddHealth > MAX_ADD_HEALTH)
    {
        return false; // 이 경우 호출자의 연결이 끊깁니다!
    }

    return true; // 이 경우 RPC가 호출됩니다!
}

💡 info
클라이언트-서버 RPC는 '_Validate' 함수가 필요합니다. 이는 안전한 서버 RPC 함수를 장려하고, 모든 파라미터가 알려진 입력 제약 조건에 맞는지 쉽게 확인할 수 있도록 하기 위함입니다.

profile
언리얼 엔진 주니어(신입) 개발자 | 소설 쓰는 취준 개발자

0개의 댓글