언리얼/이득우 네트워크 멀티플레이

[이득우 네트워크 멀티플레이] 08. RPC 기초

곰바닥 2024. 8. 21. 19:14

목표

RPC의 기본 개념과 동작 원리를 이해하기

언리얼 C++에서 다양한 RPC를 사용하는 방법을 학습하기

프로퍼티 리플리케이션과 RPC와의 차이점 이해하기

 

RPC 기초

RPC : Remote Procedure(함수) Call의 약자로 로컬에서 실행되지만 다른 머신에서 원격으로 호출되는 함수.

서버와 클라이언트 간 빠르게 명령을 주고받는 데 사용한다.

> 언리얼 엔진에서 클라이언트에서 서버로 통신하는 유일한 수단이다.

 

RPC 주로 이펙트나 사운드 재생, 파티클 등 액터의 핵심적인 기능과는 무관한 비신뢰성 게임플레이 이벤트를 위해 사용된다.

 

언리얼에서 RPC 함수를 만드는 방법은 쉽다.

UFUNCTION()에서 원하는 RPC에 해당하는 지정자를 설정해 주고 접미사로 _Implementation을 붙여주면 된다.

예를 들어 헤더파일에서 ClientRPCFunction이라 선언하면 정의는 ClientRPCFunction_Imlementation로 정의해 주면 된다.


Client RPC

서버에서 클라이언트로 호출하는 RPC

이를 활용해 특정 클라이언트에게만 명령을 보낼 수 있음

 

서버에서 명령을 보낼 클라이언트의 오너십을 소유한 액터를 사용해야함(AActor::GetNetConnection)

>즉 액터의 오너십에 의해 RPC의 호출 여부가 결정된다


Server RPC

클라이언트에서 서버로 호출하는 RPC

언리얼 엔진 구조에서 유일하게 클라이언트가 서버의 함수를 호출할 수 있는 기능이다.

 

서버 쪽에서 클라이언트의 명령을 검증할 수 있는 함수를 구현할 수 있다.

> 클라이언트의 명령을 검증하는 이유는 이것이 악의적인 것인지 혹은 변조됐는지 확인하기 위해서다.

 

Client RPC와 동일하게 서버와 동일하게  오너십이 있는 액터를 사용해야 한다

오너십이 있는 액터 : 가장 바깥 오너 액터가 커넥션에 대한 소유권이 있는 액터를 의미한다.  AActor::GetNetConnection 함수의 정의를 확인해 보면 이해하기 쉽다. 


NetMulticast RPC

서버를 포함해 모든 플레이어에게 명령을 보내는 RPC

 

만약 서버에서 호출되면 서버, 모든 클라에서 함수가 호출되고, 

클라이언트에서 호출되면 로컬에서만 호출된다.

 

프로퍼티 리플리케이션과 유사하게 연관성 기반으로 동작한다.(오너십이 없어도 동작)

> 즉 연관성이 있다면 AutonomousProxy 든 지 SimulatedProxy 든지 상관없 호출됨

 

프로퍼티 리플리케이션과 유사하지만 다른 용도로 사용한다. 이 다른 용도는 후술


RPC 키워드

UNFUNCTION에서 사용하는 지정자 키워드를 정리해 봤다.

Unreliable : RPC 호출을 보장하지 않는 옵션. 즉 원격 호출을 명령했지만 무시될 수 있다. 빠르다.

 Reliable : RPC 호출을 보장해 주는 추가 옵션. 부하 때문에 정말 필요할 때만 호출

WithValidation : 서버에서 검증 로직을 추가로 구현할 때 추가하는 옵션. 서버 RPC에서만 사용한다. 


RPC 사용 시 주의할 점

각 RPC 종류마다 올바르게 사용할 것

> Client, NetMulticast는 서버에서만 호출

> Server는 클라이언트에서 호출하지만. 플레이어로 참여하는 리슨서버의 경우 서버에서 호출이 가능하다

> Client, Server는 오너십을 가지고 있는 액터에서 호출한다

 

Tick 및 빈번하게 호출되는 함수에 Reliable RPC를 사용하지 말 것

NetMulticast RPC의 잦은 사용은 네트워크 부하를 가중시키니 신중을 기하자

게임플레이 및 액터 상태에 영향을 미치는 경우 RPC보다 프로퍼티 리플리케이션을 사용할 것 

 

 

HasAuthority 함수를 사용해 호출 지점에 대해 파악하고

IsLocalController 또는 IsLocallyControlled 함수를 사용해 오너십을 파악한다 


프로퍼티 리플리케이션 VS NetMulticast RPC

유사점

  • 서버와 모든 클라이언트의 지정한 함수를 호출할 수 있다.
  • 지정한 데이터 전송을 보장할 수 있다.
  • 액터의 오너십과 무관하게 연관성으로 동작한다.

 

차이점

  • 프로퍼티 리플리케이션으로 설정한 데이터는 클라이언트에 반드시 동기화된다.
    • (RPC 전송의 Reliability와 다른 개념)
  • NetMulticast RPC를 호출한 타이밍에 클라이언트가 없으면 해당 데이터를 받을 방법이 없음

 

즉 프로퍼티 리플리케이션은 게임에 영향을 미치는 데이터에 사용하지만

NetMulticast RPC는 게임과 무관한 휘발성 데이터에 사용한다.


네트워크 멀티플레이의 구현을 위한 4원칙

  1. 클라이언트의 명령은 Server RPC를 사용한다
  2. 중요한 게임 플레이 판정은 서버에서 처리한다
  3. 게임 플레이에 영향을 주는 중요한 정보는 프로퍼티 리플리케이션을 사용한다.
  4. 클라이언트의 시각적인 효과(Cosmetic)는 Client RPC와 Multicast RPC를 사용한다

네트워크 멀티플레이에서 공격 기능 구현 예제


액터 컴포넌트 리플리케이션

  • 언리얼에서 리플리케이션의 주체는 액터다.
  • 액터가 소유한 언리얼 오브젝트에 대해 리플리케이션 진행이 가능하다
    • 이렇게 액터에 종속된 언리얼 오브젝트를 서브 오브젝트라고도 한다.
  • 스탯을 관리하는 액터 컴포넌트의 리플리케이션 설정
    • 액터에서 컴토넌트의 리플리케이션을 지정 : SetIsReplicated(true)
    • 리플리케이션이 준비되면 호출되는 이벤트 함수 : ReradyForReplication