2026. 6. 4. 20:55ㆍTIL

RPC 공식문서
https://dev.epicgames.com/documentation/unreal-engine/rpcs-in-unreal-engine?application_version=5.1
Remote Procedure Calls in Unreal Engine | Unreal Engine 5.7 Documentation | Epic Developer Community
Call functions on remote machines across a network in Unreal Engine.
dev.epicgames.com
RPC가 필요한 이유
RPC(Remote Procedure Call)은 원격 함수 호출을 의미한다.
멀티플레이 이전에는 함수를 호출하면 호출한 PC와 실행되는 PC가 같았지만 멀티플레이에서는 이것으로 부족하다.
예를 들어 내가 총을 쐈을 때, 총구 이펙트와 총소리는 다른 플레이어의 클라이언트 화면에도 보여야 한다. 그런데 내 PC에서만 함수를 실행하면 내 화면에만 이펙트가 나온다.
이 문제를 해결하기 위해 RPC에 대해서 공부해보겠다.
"내 PC에서 호출하는데, 다른 PC에서 실행되게 할 수 있다."
- 클라이언트에서 호출 → 서버에서 실행
- 서버에서 호출 → 모든 클라이언트에서 실행
- 서버에서 호출 → 특정 클라이언트에서 실행
언리얼에서 RPC를 언제 쓰는지?
RPC는 주로 게임에 큰 영향을 끼치지 않는 일시적인 효과에서 사용한다.
- 총구 이펙트, 파티클
- 발소리, 총소리 같은 사운드
- 히트 연출, 폭발 이펙트
중요한 로직에 사용하지 않는 이유는 RPC는 전달이 보장되지 않을 수 있기 때문이다.
HP감소, 스폰, 점수 계산처럼 게임에 중대한 영향을 끼치는 것들은 프로퍼티 레플리케이션을 사용하는 것이 맞다.
Call / Invoke
Call은 정적인 의미이다. 컴파일 타임에 어떤 함수를 호출할지, 어디서 실행될지가 확정된다.
일반 함수호출이 여기에 해당된다.
Invoke는 동적인 의미이다. 런타임에서 어떤 함수를 어느 PC에서 실행할지가 결정된다.
함수 포인터, 가상 함수(동적 바인딩), RPC가 여기에 해당된다.
Actor Ownership - RPC 작동의 전제 조건
RPC가 제대로 작동하려면 액터의 소유 관계(Ownership)가 올바르게 설정되어 있어야 한다.
다음과 같은 기본조건이 있다.
- 액터는 서버에서 스폰되어야 한다.
- bReplicates = true여야 한다.
그리고 SetOwner(PlayerController)를 호출하면 이 액터가 누구 소유인지 결정된다.
| 케이스 | 조건 | 예시 |
| Client-Owned | SetOwner(PC) 호출, 그 PC가 이 클라이언트의 PC | 내 플레이어 캐릭터 |
| Owned by Different Client | SetOwner(PC) 호출, 그 PC가 다른 클라이언트의 PC | 내 화면에 보이는 친구 캐릭터 |
| Server-Owned (= Unowned) | SetOwner() 호출 없음 | 보물상자, NPC, 환경 오브젝트 |
RPC가 어디서 실행될지는 "누가 이 액터를 소유하고 있는가"에 따라 달라진다.
클라이언트 → 서버 방향의 Server RPC는 Client-Owned Actor에서만 제대로 동작한다. Owner가 없는 Server-Owned Actor에서 호출하면 NetConnection을 찾지 못해서 그냥 무시된다.
Server / Client / NetMulticast 키워드
이 세 키워드는 UFUNCTION() 매크로에 붙여서 RPC로 만드는 선언이다. 키워드의 의미는 "어느 PC에서 실행시켜 달라는 요청"이다.
Server키워드
클라이언트가 서버한테 요청하는 방향이다.
UFUNCTION(Server, Reliable, WithValidation)
void ServerDoSomething();
클라이언트에서 ServerDoSomething() 호출
→ 네트워크를 통해 서버로 전달
→ 서버에서 ServerDoSomething_Implementation() 실행
Client 키워드
서버가 특정 클라이언트한테 요청하는 방향이다.
UFUNCTION(Client, Reliable)
void ClientDoSomething();
서버에서 ClientDoSomething() 호출
→ 네트워크를 통해 오너 클라이언트로 전달
→ 오너 클라이언트에서 ClientDoSomething_Implementation() 실행
NetMulticast 키워드
서버가 모두한테 동시에 브로드캐스트하는 방향이다.
UFUNCTION(NetMulticast, Unreliable)
void MulticastDoSomething();
서버에서 MulticastDoSomething() 호출
→ 서버에서도 실행
→ 클라이언트 A에서도 실행
→ 클라이언트 B에서도 실행
이 키워드는 모든 PC에 전달하기 때문에 네트워크 부하가 크다.
그래서 Tick()같이 매 프레임 호출되는 곳에서 쓰면 안된다. 주로 폭발 이펙트, 사망 연출처럼 모든 클라이언트 화면이 동시에 보여야하는 시각 효과에 사용된다.
WithValidation
Server 키워드 RPC에는 WithValidation을 붙이는 것이 권장된다. 이걸 붙이면 함수가 두 개로 나뉜다.
void ServerDoSomething_Validate(); // 실행할지 말지 결정
void ServerDoSomething_Implementation(); // 실제 로직
실행 흐름은 다음과 같다.
클라이언트가 ServerDoSomething() 호출
→ 서버에서 Validate() 먼저 실행
→ true 반환: Implementation() 실행
→ false 반환: 실행 안 함 + 해당 클라이언트 연결 강제 종료
서버에서 실행되는 로직은 게임에 직접 영향을 끼친다.
해커가 조작된 값을 담아서 RPC를 날릴 수 있기 때문에 Validate()에서 값의 정상 여부를 먼저 판단하고, 비정상이면 차단하는 방어막 역할을 한다.
bool AMyActor::ServerSendChatMessage_Validate(const FString& Message)
{
if (Message.Len() > 200) // 메시지가 너무 길면 차단
return false;
return true;
}
Unrealiable / Reliable
RPC는 네트워크를 통해 전달되기 때문에 패킷이 중간에 유실될 수 있다. 이를 처리하는 방식이 두 가지이다.
Unrealiable
- 전달을 보장하지 않는다.
- 패킷이 유실되면 그냥 넘어간다.
- 오버헤드가 낮고 빠르다.
- 유실돼도 큰 문제가 없는 코스메틱 요소에 사용된다.
Reliable
- 전달을 보장한다.
- 패킷이 유실되면 수신 확인이 될 때까지 재전송한다.
- 오버헤드가 크지만 반드시 실행되어야 하는 로직에 사용한다.
| 키워드 | 전달 보장 | 오버헤드사용 | 예시 |
| Unreliable | X | 낮음 | 발소리, 총구 이펙트 |
| Reliable | O | 높음 | 데미지, 스폰, 채팅 메시지 |
그렇지만 Reliable을 남발하면 재전송 요청이 쌓여서 네트워크가 막힐 수 있다. 꼭 필요한 곳에서만 사용해야 한다.
잘못된 예:
Tick()에서 매 프레임 Reliable RPC 호출
→ 패킷 유실 시 재전송 요청이 폭증 → 네트워크 과부하
핵심 포인트
- RPC는 호출하는 PC와 실행하는 PC를 분리할 수 있는 통신 기법이다.
- RPC는 코스메틱(이펙트, 사운드) 위주로 사용하고, 중요한 로직은 프로퍼티 레플리케이션을 사용한다.
- Server RPC는 Client-Owned Actor에서만 제대로 동작한다. Owner가 없으면 NetConnection을 찾지 못해 무시된다.
- Client RPC는 오너 클라이언트에서만 실행된다.
- NetMulticast RPC는 서버에서만 호출해야 하고, 부하가 크므로 Tick에서 쓰면 안 된다.
- WithValidation은 서버 RPC의 위변조 방지용이다. false 반환 시 해당 클라이언트 연결이 강제 종료된다.
- Reliable은 꼭 필요한 곳에만 써야 한다. 남발하면 네트워크 과부하가 생긴다.
'TIL' 카테고리의 다른 글
| <멀티플레이 기초> 채팅 구현 (RPC 실전 적용) (0) | 2026.06.07 |
|---|---|
| 게임 멀티플레이 기초 - 서버와 클라이언트 <NetMode, NetRole> (0) | 2026.06.03 |
| < 언리얼 C++ > GameMode (0) | 2026.04.12 |
| < 언리얼 C++ > 회전 발판과 움직이는 장애물 만들기 (0) | 2026.04.11 |
| [TIL 46일차] <언리얼 C++> 리플렉션 시스템 (2) | 2026.04.09 |