Unreal Engine - RPC 기초 실습
튜토리얼로 ThirdPerson 템플릿 생성해서 플레이어 컨트롤러 생성부터 진행해 RPC 에 대해 알아보자.
플레이어 컨트롤러는 게임 구동시 각자의 머신에서 한 대만 있으므로 구별하기가 쉬웠다.
실습 시나리오는 플레이어 컨트롤러 블루프린트에서 호출하고 서버가 함수를 실행하는 코드를 작성할 것이다.
Custom Event 노드 생성
일종의 콜백함수의 역할을 하는 Custom Event 추가해 문자열 출력을 붙인다.

- 노드 추가 Custom Event, Print String, Event BeginPlay, Call Function(Server RPC)
- Custom Event -> Print String
- Custom Event 생성하고 이름을 Server_RPC 으로 변경한다.
- 서버에서 실행하고 싶은 노드를 여기로 붙이도록 한다.
- BeginPlay -> Call Function(Server RPC)
실행결과

Client 2: Hello RPC
Server: Hello RPC
Client 1: Hello RPC
Server: Hello RPC
Server: Hello RPC
- 플레이어는 3명 지정하고, Listen Server로 구동한다.
응? Server 가 왜 세 번 호출했지. 라고 생각할 수 있다.
Server의 Outliner 살펴보면 Player Controller 생성한 플레이어만큼 있는 것을 확인할 수 있고, 인스턴스 세 번 생성하였으므로 세 번 호출한 것이다.
그리고 RPC를 설정하지 않았으므로 클라이언트는 본인이 호출한것만 실행한다.
RPC 설정 - Run on Server
먼저 클라이언트에서 호출을 막을 것이므로 Switch Has Authority 함수를 가져와 BeginPlay 노드로 연결하였다.

- Switch Has Authority 노드 추가
- BeginPlay -> Switch Has Authority -> Call Function(Server_RPC)
Custom Event 에서 레플리케이트 항목을 "Run on Server"으로 설정한다.
실행시 다음과 같은 메시지가 출력할 것이다.
Server: Hello RPC
Server: Hello RPC
Has Authority 로 권한이 없는 머신에서 실행하라는 코드를 넣었다. 그로인해 호스트 머신는 클라이언트와 서버를 겸직하고 있기에 Authority 가 있다. 호스트는 제외되고 결국 남은 클라이언트들이 호출을 보낸 것을 실행한다.
우리들이 원하는 것은 각자의 플레이어가 조종하는 스폰된 액터가 3개이므로 세 번 출력해주도록 해야한다.

- Is Local Controller, Branch 노드 추가
- Event BeginPlay -> Branch -> Call Function(Server RPC) 연결
- Is Local Controller -> Branch (Condition 핀)
노드에서 Switch Has Authority 대신 Is Local Controller 와 Branch 노드를 추가해 로컬 컨트롤러인지 검증하는 로직을 추가한다.
실행 결과가 스폰된 액터만큼 출력에 성공하였다.
Server: Hello RPC
Server: Hello RPC
Server: Hello RPC
동작 과정
다음 플레이어 3명의 컨트롤러가 구성되어 있다고 보자.
- Server
- Player Controller 0
- Player Controller 1
- Player Controller 2
- Client1
- Player Controller 0
- Client2
- Player Controller 0
Is Local Controller 검증을 하게 되면 메시지 호출 할 후보 클래스는 다음과 같다.
RPC 함수 요청 후보 클래스
- Server
- Player Controller 0
- Client1
- Player Controller 0
- Client2
- Player Controller 0
Server의 Player Controller 1, 2 컨트롤러는 본인 것이 아니므로 제외하고 클라이언트는 Call Function 호출하여 서버에서 실행한다.
RPC 대기 중이던 이벤트가 호출을 받아 실행한다.
- Server
- Player Controller 0 <- Server
- Player Controller 1 <- Client 1
- Player Controller 2 <- Client 2
RPC 설정 - RPC on owning Client
다음으로 서버가 함수를 호출해 클라이언트가 실행하는 것을 구성해보자.
이번에도 신규로 만든 PlayerController 블루프린트에서 작업한다.
BeginPlay 에서 자신은 isServer를 체크하고 Client_RPC 라는 커스텀 이벤트를 통해 실행시키도록 할 것이다.
Client_RPC 의 레플리케이트 항목을 RPC on owning Client 로 설정한다.
owning 이름의 의미는 월드에서 플레이어컨트롤러를 소유한 클라이언트에게만 실행한다는 의미이다.
플레이어컨트롤러는 서버와 클라이언트가 서로 갖고 있다. 클라 입장에서는 1:1 통신이 되며 제3자에게 공개하지 않고 서버에게만 정보를 주고 받을 필요가 있다.
블루 프린트 설정하기

- 추가 노드: Custom Event, Print String, BeginPlay, Delay, Branch, Is Server, Call Function (Client RPC)
- Custom Event(Client_RPC) -> Print String
- BeginPlay -> Delay -> Branch -> Call Function(Client_RPC)
- Is Server -> (Condition 핀)Branch
Custom Event 디테일에서 레플리케이트를 Run on Owning Client으로 설정한다.
실행결과
게임은 플레이어 3명과 Listen Server로 구동하였다.
Server: Hello RPC
Client1: Hello RPC
Client2: Hello RPC
동작 과정
다음 플레이어 3명의 컨트롤러가 다음과 같이 구성되어 있다고 보자.
- Server
- Player Controller 0
- Player Controller 1
- Player Controller 2
- Client1
- Player Controller 0
- Client2
- Player Controller 0
IsServer 를 체크하므로 Server의 Player Controller 0, 1, 2 순으로 Call Function 함수를 호출할 것이다. 이 때 Player Controller 0은 자신의 것이므로 메시지를 출력한다. 나머지 Player Controller로 소유하고 있는 Client에게 함수를 실행하라고 명령한다.
RPC 함수 호출
- Server
- Player Controller 0 -> Server
- Player Controller 1 -> Client 1
- Player Controller 2 -> Client 2
Client에서는 자신의 소유가 아닌 것은 호출을 받지 않으므로 본인외의 메시지 출력을 하지 않는다. 그리고 서버에서 본인 것이 수신받았다면 Custom Event 함수를 실행해 메시지를 출력하게 될 것이다.
RPC 함수 이벤트 실행
- Server
- Player Controller 0
- Client1
- Player Controller 0
- Client2
- Player Controller 0
Multicast
지금까지 PlayerController 으로 진행해왔으나, 이번에는 다른 클래스로 실습해보도록 한다.
Character 클래스로 상속 받고 있는 BP_ThirdPersonCharacter 블루프린트에서 진행한다.

BP_ThirdPersonCharacter
- 추가 노드: Custom Event, Print String, BeginPlay, Delay, Branch, Is Server, Call Function (MultiCast_RPC)
- Custom Event(MultiCast_RPC) -> Print String
- BeginPlay -> Delay -> Branch -> Call Function(Multi Cast RPC)
- Is Server -> (Condition 핀)Branch
IsServer는 Server 에서 발송하라고 명확히 인식하고 싶었다. 그리고 Custom Event 레플리케이트 설정을 Multicast로 설정한다.
각자의 출력 결과는 다음과 같다.
[BP_ThirdPersonCharacter0] Server: Hello RPC
[BP_ThirdPersonCharacter1] Client1: Hello RPC
[BP_ThirdPersonCharacter1] Client2: Hello RPC
[BP_ThirdPersonCharacter1] Server: Hello RPC
[BP_ThirdPersonCharacter0] Client1: Hello RPC
[BP_ThirdPersonCharacter2] Client2: Hello RPC
[BP_ThirdPersonCharacter2] Server: Hello RPC
[BP_ThirdPersonCharacter2] Client1: Hello RPC
[BP_ThirdPersonCharacter0] Client2: Hello RPC
동작 과정
다음 플레이어 3명의 캐릭터가 월드에 구성되어 있다.
- Server
- BP_ThirdPersonCharacter 0
- BP_ThirdPersonCharacter 1
- BP_ThirdPersonCharacter 2
- Client1
- BP_ThirdPersonCharacter 0
- BP_ThirdPersonCharacter 1
- BP_ThirdPersonCharacter 2
- Client2
- BP_ThirdPersonCharacter 0
- BP_ThirdPersonCharacter 1
- BP_ThirdPersonCharacter 2
IsServer 로 Server만 Multicast 호출하도록 하였다.
RPC 함수 호출
- Server
- BP_ThirdPersonCharacter 0
- BP_ThirdPersonCharacter 1
- BP_ThirdPersonCharacter 2
이렇게 되면 3번 호출 하므로 각 클라이언트는 다음과 같이 받게 될 것이다.
RPC 함수 이벤트 실행
- Server
- BP_ThirdPersonCharacter 0 <- Server
- BP_ThirdPersonCharacter 1 <- Client 1
- BP_ThirdPersonCharacter 2 <- Client 2
- Client1
- BP_ThirdPersonCharacter 0 <- Server
- BP_ThirdPersonCharacter 1 <- Client 1
- BP_ThirdPersonCharacter 2 <- Client 2
- Client2
- BP_ThirdPersonCharacter 0 <- Server
- BP_ThirdPersonCharacter 1 <- Client 1
- BP_ThirdPersonCharacter 2 <- Client 2
총 9개 메시지를 출력한다. 각자 메시지를 한번만 받고 싶다면 Custom Event 앞에 Is Local Controller 를 붙이도록 한다.
TCP - Reliable
언리얼 엔진의 레플리케이트는 기본 값으로 UDP 로 보내게 되어있다. 한번 패킷을 보내면 정말로 받았는지 확인하는 과정이 없다.
그러나 UDP가 아닌 TCP 핸드셰이크로 설정하는 방법이 있다.
Custom Event 디테일의 레플리케이션 항목에서 해당 옵션을 체크한다.
이 옵션을 체크하면 패킷이 정상적으로 보냈는지 확인하는 과정을 거치게 된다.
Run on Owning Client 콘텐츠 용도
해당 기능을 가지고 어떤 용도로 사용하면 좋을지 생각해볼 수 있다.
- 게임이 끝나서 결과를 클라이언트로 전달이 필요할 때
- 운영자가 메시지를 클라이언트로 전달이 필요할 때