RPC (Remote Procedure Call, 원격 프로시저(함수) 호출)
- 원격 컴퓨터에 있는 함수를 호출할 수 있도록 만든 통신 프로토콜 (로컬 호출, 원격 실행)
- 네트워크 멀티플레이에서서버와 클라이언트 간 빠르게 행동을 명령하고 정보를 주고받는데 사용
- Unreal Engine에서 클라이언트에서 서버로 통신하는 유일한 수단을 제공
- 서버에서 클라이언트로 전파되는 방향성을 가지며
클라이언트에서 커넥션을 소유하는 Actor는 서버로 명령을 내릴 수 있다. - Sound, Particle, Actor의 핵심적인 기능과 무관한 Costemic 같은 작업을 하는 이벤트에 유용하게 사용된다.
RPC 종류
Client RPC -> UFUNCTION(Client)
서버에서 함수를 호출, 클라이언트 실행
위 RPC를 사용해 특정 클라이언트에게만 명령을 보낼 수 있다.
서버에서 명령을 보낼 클라이언트의 커넥션을 소유한 Actor를 사용해야한다.
즉, Actor의 오너십을 통해 RPC 호출 여부가 결정된다.
(AActor::GetNetConnection()을 통해 확인 가능. Actor의 오너가 가진 커넥션을 반환한다.)
h파일에 다음과 같이 선언해준다.
cpp에 다음과 같이 선언해준다. h 파일에 선언한 함수명에 _Implementation을 추가로 넣어서 함수명을 만들어야한다.
BeginPlay에 서버일 경우 다음과 같이 실행하도록 한다.
ClientRPC의 경우 커넥션을 가지지 않으면 서버에서 _Implementation이 호출이 된다.
그러나 Client가 커넥션을 가진 이후엔 서버에선 호출되지 않으며 Client에서만 _Implementation이 호출된다.
이때 이 함수를 실행시키는 Actor가 커넥션(오너십)이 없다면

다음과 같이 No owing connection이라는 warning이 뜬다.

다음과 같이 클라이언트 입장에서 FirstPlayerController가 커넥션을 소유한 오너이기 때문에
GetFirstPlayrController를 오너로 지정한다.
여기서 주의할 점은 SetOwner()는 클라이언트에서 수행하면 의미가 없다.
클라이언트의 Actor는 서버의 Actor를 복제한 것이기에 서버에 있는 Actor의 Owner가 설정되어야한다.
또한 클라이언트가 해당 서버에 들어오고 PlayerController가 만들어질 때까지의 여유를 두고 오너십을 설정해야한다.

간단하게 서버의 BeginPlay에서 10초뒤에 서버에 있는 모든 PlayerController를 들고와서
첫번째 클라이언트만 SetOwner를 해주는 로직을 추가한다.
이 코드는 10초 뒤에 클라이언트가 들어오면 Owner가 설정되지 않아서 Light가 변경되지 않는다.

World에 있는 APlayerController를 쉽게 다음과 같이 가져올 수도 있다.
오너십을 가지고 있는지 Check하는 함수
Controller : IsLocalController 함수 / Pawn : IsLocallyControlled 함수
오너십을 가지지 않는 Actor가 호출해도 에러가 나지 않는 경우가 존재하기 때문에 오너십을 가지고 있는지
체크해서 사용하는 것이 좋다.
Server RPC -> FUNCTION(Server)
클라이언트에서 호출, 서버 실행 (유일하게 클라이언트가 서버의 함수를 호출 가능하다.)
서버쪽에서 클라이언트의 명령을 검증할 수 있는 함수를 구현할 수 있다.
Client RPC와 동일하게 서버와의 커넥션을 소유한 액터를 사용해야한다.
h파일에 다음과 같이 선언해준다.
cpp에 다음과 같이 선언해준다. h 파일에 선언한 함수명에 _Implementation을 추가로 넣어서 함수명을 만들어야한다.
클라이언트에서 ServerRPC_ChangeColor를 실행하면
서버에서 ServerRPC_ChangeLightColor_Implementaion()을 실행한다.
이 ServerRPC도 커넥션이 없으면 동작하지 않는다.
다음과 같이 UFUNCTION에 WithValidation 키워드를 추가하면
함수명_Validate를 추가해야한다. 이때 true를 리턴하면 검증에 통과했다는 것이고 false는 검증에 실패한 것이다.
false일 경우에 즉시 해당 클라이언트가 차단이 되어 접속을 끊는다.
NetMulticast RPC - >UFUNCTION(NetMulticast)
서버에서 함수 호출, 서버 & 모든 클라이언트에서 실행
프로퍼티 리플리케이션과 유사하게 연관성 기반으로 동작 (커넥션을 소유하지 않아도 동작)
클라이언트에서 호출 시 해당 클라이언트만 실행 (통신이 아예 일어나지 않는다.)
다른 RPC에 비해 부하가 크기 때문에 자주 호출하면 좋지 않고 자주 실행되지도 않는다.
헤더 파일에 다음과 같이 선언해주고
cpp에 다음과 같이 선언해준다. h 파일에 선언한 함수명에 _Implementation을 추가로 넣어서 함수명을 만들어야한다.
이제 다시 BeginPlay에서 Timer를 사용해서 반복해서 계속 함수를 불러보자.
지금 보면 위의 BeginPlay는 _Implementation이 없는데 위의 if문을 보면 서버가 실행한다.
서버가 호출할 땐 _Implementaion이 없이 사용하고 서버에서 MulticastRPC_ChangeLightColor를 호출하면
클라이언트와 서버가 MulticastRPC_ChangeLightColor _Implementaion을 엔진에서 자동으로 실행함.
RPC 선언과 관련된 키워드
Unreliable : RPC 호출을 보장하지 않는 옵션. 데이터 전송을 보장하진 않지만 빠르게 보낼 수 있다. (ex. 움직임 )
Reliable : RPC 호출을 보장해주는 옵션. 내부적으로 도착했는지 확인하는 작업을 진행하기에 필요할 때만 호출하는 것이 좋다.
너무 빈번하게 호출되면 강제로 접속이 끊기게 된다.
(ex. 충돌 이벤트, 무기 발사, 시작 & 종료 등)
WithValidation : 서버에서 검증 로직을 추가로 구현할 때 추가하는 옵션 (Server RPC에서만 사용)
첫번째 키워드 | 두번째 키워드 (UE5 부터 2번째 키워드까지 입력) |
세번째 키워드 |
Client | Unreliable | WithValidation |
Server | Reliable | |
NetMulticast |
RPC 조건 및 주의사항
- Actor에서 호출되어야한다.
- Actor는 반드시 Replicated여야한다.
- 서버에서 호출되고 클라이언트에서 실행되는 RPC의 경우 해당 Actor를 실제 소유하고 있는
클라이언트에서만 실행된다. - 클라이언트에서 호출되고 서버에서 실행되는 RPC의 경우 클라이언트는 RPC가 호출되는 Actor를 소유해야한다.
- Multicast RPC는 예외이다.
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/networking-overview-for-unreal-engine
네트워크 개요에 중요한 사항들이 작성되어있다.
꼭 한번 살펴보고 사용하면 좋을 듯하다.
Property Replication vs NetMulticast PRC
유사점
- 서버와 모든 클라이언트의 지정한 함수를 호출할 수 있음
- 지정한 데이터 전송을 보장할 수 있음 (RPC는 Reliability 사용)
- Actor의 오너십과 무관하게 연관성으로 동작함.
차이점
- Property Replication으로 설정한 데이터는 클라이언트에 반드시 동기화 됨.
(RPC의 Reliability는 전송을 보장하는 것이지 반드시 동기화는 아님) - NetMulticast RPC를 호출한 타이밍에 클라이언트가 없으면 데이터를 받을 수 길이 없음.
Property Replication은 데이터를 보존하고 새롭게 클라이언트가 접속 시 보존한 값을 갱신할 수 있음
(ex. 3vs2 게임에서 Effect가 발생했을 때 A 클라이언트가 들어오면 A는 해당 Effect를 받아서 화면에 나타낼 수 없지만
Property Replication으로 되어있는 게임 Play중인 인원은 3vs3으로 갱신되어 A 클라이언트에게 보낼 수 있음
&
5초뒤에 서버에서 조명의 색상이 변한다(Red -> Blue)고 가정하고 이 조명의 색상이
Property Replication일 경우 새로운 클라이언트가 5초뒤에 접속해도 색상이 변하고 (Blue)
NetMulticast RPC일 경우 새로운 클라이언트가 5초뒤에 접속하면 색상은 변하지 않는다.(Red))
Property Replication : 게임에 영향을 미치는 데이터에 사용한다.
NetMulticast RPC : 게임과 무관한 휘발성 데이터(사라져도 되는 데이터)에 사용한다.