개인 공부/네트워크

Unreal Engine 의 RPC (2)

workbench34 2025. 3. 21. 19:27

 저번 시간에는 Replication 에 대해 알아보았다. Replication 은 서버가 클라이언트에게 변경된 게임의 데이터들을 실시간으로 전달해 주는 역할이었다. 즉, 특정 액터의 데이터나 플레이어들의 데이터가 바뀌면 서버가 클라이언트에게 갱신된 값들을 복제해 주는 역할이다. 그러나 여기서 의문이 드는데...

 

그럼 클라이언트는 서버에 어떻게 데이터를 보냄?

 당연하게도 변경된 데이터를 서버도 알아야하기에 클라이언트가 서버에게 데이터를 보내줄 방법이 필요하다. Replication 은 저번 시간에 배웠듯이 서버에서 클라이언트로의 일방 통행임으로 Replication 을 이용하여 클라이언트가 서버에게 데이터를 전송할 수 없다. 그렇기에 우리는 RPC - RemoTe Procedure Call 을 사용해야한다.

 

RPC 란 무엇인가?

일단 이름부터 알아보자. Remote - 원격의, Procedure - 절차 , Call - 부름 으로 원격 절차 부름 이라는 뜻을 가지고있다. 뜻을 알아도 이게 도통 무엇인지 알수가 없다. 이는 Procedure 가 컴퓨터 구조에서 어떤 역할을 하는지 알아야 하기 때문인데 간단하게 알아보자.

 

RPC에서의 프로시저 의미:

  • 원격 실행 가능한 함수 또는 메서드:
    • RPC에서 프로시저는 원격 서버에서 실행될 수 있는 함수 또는 메서드를 의미한다. 클라이언트가 마치 로컬 함수를 호출하는 것처럼 원격 서버의 프로시저를 호출하여 작업을 수행한다.
  • 분산 시스템에서의 작업 단위:
    • RPC는 분산 시스템에서 서로 다른 컴퓨터 간의 통신을 가능하게 한다. 이때 프로시저는 원격 시스템에서 수행되는 작업의 단위가 된다.

 단순하게 이야기 하자면 Procedure 는 원격서버에서 실행될 수 있는 함수 또는 메서드이다.

 

 RPC 는 원격 머신에서 함수를 호출하는 명시적인 방법이다. 여기서 명시적이라는 단어가 어색할 수 있는데 이는 호출할때 명확한 인터페이스 정의를 의미함과 동시에 명확한 호출 과정을 의미한다. 이는 모호함을 제거하고 오류 발생 가능성을 줄여준다는 의미이기도 하다.

 

 Unreal 에서 RPC 는 UFUNCTION 에 Server, Client, NetMulticast 같은 지정자를 붙여 만들며, 이를 호출하면 설정된 대상 (Server 또는 Client들) 에서 함수가 실해된다.

 

 예를 들자면, Client 에서 "FrieWeapon" 이라는 Server RPC 를 호출하면, 그 함수가 Server 측에서 실행되어 총알 발사 처리를 한다. Replication 이 상태를 지속적으로 동기화해 클라이언트 간의 차이를 줄이는 것이라면, RPC 는 특정 순간에 실행되는 동작(Event)을 원격으로 호출하는 것이다.

 

Replication 과 RPC 의 차이

 Relication 은 Server 에서 Client 의 단방향 자동 동기화만 지원한다. 그러나 RPC 는 아래의 표와 같이 종류에 따라 방향 지정이 가능하다.

출처-내일 배움 캠프

 보면 의문이 들 수 있다.

'그럼 그냥 RPC 로 모든 것을 만들면 되지 않나? 어짜피 RPC 는 방향 지정 동기화도 가능하고, Multicast RPC 로 브로드 캐스팅 하기도 편해보이는데.'

 이는 Replication 과 RPC 의 특성이 다르기 때문이다.

 

 Replication 은 실시간으로, 지속적인 상태로 동기화를 하기때문에 이는 계속 유지되어야 하는 데이터들의 편차를 줄이기 좋다. 즉, State 기반 이라는 의미이다. (Property 를 사용한다.)

 

 반면, RPC 는 특별한 Event 를 호출할 때 사용한다. 만약 FPS 게임이라면 총알의 갯수는 Replicated Property 로 만들어 계속 변할 수 있고 현재 값을 유지 해주어야 한다. 그러나 플레이어가 총을 쏘았다는 이벤트는 RPC 로 Server 에 보내는 형식이다.

 

 또한 기술적으로도 다른데 Replication 은 Unreal Engine 에서 알아서 (프레임마다 혹은 필요한 시점마다) 값을 보내주며 내부적으로 최적화된다. RPC 는 개발자가 필요한 순간에 직접 호출해야 하고, 호출할 때마다 네트워크 Packet 을 생성한다.

 

 마지막으로 순서인데 전에 설명하였듯이 Replication 이 여러 변수를 가지고있다면 한번에 뭉쳐서 보내기에 특정 순서를 보장하지 않는다. 이는 먼저 보낸 데이터가 뒤에 도착할수도 있고 뒤에 보낸 데이터가 더 빨리 도착할수도 있다는 의미이다. 그러나 PRC 는 Reliable 로 보낼지 Unreliable 로 보낼지에 따라 선택할 수 있는데, 같은 종류의 RPC 들끼리는 호출 순서가 보장된다.

 

정리

 간단히 비유해보자면,

Replication = 값 동기화

RPC = 원격 함수 호출

 

 이다. 이 둘은 양자택일이 아니라 필요에 따라 병행해서 사용하게 된다. 앞에서 말했듯이 RPC 가 모든 것을 담당할 수 없고, Replication 또한 한계가 있다는 의미이다.

 

 예시를 들어보자. Client 가 Server RPC로 " 이 문을 열고 싶어요”라고 알리면 (Event 전달), Server는 문을 여는 권한이 있으니 문의 State에 대한 Property를 Open으로 변경하고, 그 Property를 Replication하여 모든 Client에게 알린다.

 

 여기서 생각해야 할 점은 Client 는 Server 의 Replicated Variable 을 직접 바꿀 수 없다는 점이다. Client 가 Local 환경에서 Replicated Variable 의 값을 백날 바꿔 봤자 그것은 자기 화면에만 일시적으로 바뀔 뿐, Server 나 다른 Client 에 반영되지 않는다. 그에 대해서는 반드시 Server 에 변경을 요청해야 하며, 이는 멀티플레이의 Golden Rule 이다.

 

(왠지 핑차이 나는 게임에서는 백날 때려도 나는 맞고 상대는 피하더라)

 

 정리하자면 Client에서 Server로 데이터를 전달하는 유일한 방법은 Server RPC (Run on Server)이며, 모든 Client와 Server에 반영되어야 할 게임 상태 변경은 Server에서만 해야 한다는 것이다. Client는 Server에 요청하거나, 일시적으로 자기 화면에서 보여줄 내용을 예측만 해야한다.

 

 이렇게 Replication 과 RPC 에 대해 알아보았다. 이는 멀티플레이 게임에 있어서 가장 중요한 기본이며 어떤 Value 와 Event 를 어떻게 클라이언트와 서버가 서로 소통하게 만들 것인지에 대한 최소한의 기본이다. 이를 잘 숙지하고 멀티플레이 게임을 제작하도록 하자.