본문 바로가기
Unreal Engine/멀티플레이어 게임 개발

[언리얼 멀티플레이 기초 개념] 네트워크 동기화 구현 (RPC)

by 4.41p._.m 2026. 8. 4.

1. RPC 기반 멀티플레이어 채팅 네트워크 동기화

언리얼 엔진 멀티플레이어 환경에서 클라이언트의 채팅 입력을 모든 플레이어에게 전달하려면 Server RPC(Remote Procedure Call)와 NetMulticast RPC를 조합하여 사용해야 합니다.

 

1-1. RPC 동기화 메커니즘 흐름

  1. 클라이언트 A (발신자): UI 입력창에서 메시지를 작성하고 엔터를 누르면 PlayerController의 Server RPC를 호출합니다.
  2. 서버 (Server): 클라이언트 A로부터 전달받은 Server RPC 요청을 수신하고, 이를 모든 접속자에게 전파하기 위해 NetMulticast RPC를 호출합니다.
  3. 모든 클라이언트 (All Clients): 서버가 보낸 NetMulticast RPC를 전달받아 화면(UI 또는 Screen)에 채팅 메시지를 출력합니다.

 

1-2. C++ 코드 구현

1) 헤더 파일 (CXPlayerController.h)

RPC 함수는 언리얼 리플렉션 시스템을 위해 UFUNCTION 매크로 속성을 지정해야 합니다. 채팅 메시지는 패킷 유실 없이 확실하게 전달되어야 하므로 Reliable 옵션을 붙여줍니다.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "CXPlayerController.generated.h"

UCLASS()
class CHATX_API ACXPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    ACXPlayerController();

    // UI 입력 시 호출되는 기존 메세지 설정 함수
    void SetChatMessageString(const FString& InChatMessageString);

    // 채팅 메세지 화면 출력 함수
    void PrintChatMessageString(const FString& InChatMessageString);

protected:
    // 1. 클라이언트 -> 서버 전달 (Server RPC)
    UFUNCTION(Server, Reliable)
    void ServerRPC_SendChatMessage(const FString& InChatMessageString);
    void ServerRPC_SendChatMessage_Implementation(const FString& InChatMessageString);

    // 2. 서버 -> 모든 클라이언트 전파 (NetMulticast RPC)
    UFUNCTION(NetMulticast, Reliable)
    void MulticastRPC_BroadcastChatMessage(const FString& InChatMessageString);
    void MulticastRPC_BroadcastChatMessage_Implementation(const FString& InChatMessageString);

private:
    FString ChatMessageString;
};

 

2) 소스 파일 (CXPlayerController.cpp)

#include "CXPlayerController.h"
#include "Kismet/KismetSystemLibrary.h"

ACXPlayerController::ACXPlayerController()
{
}

void ACXPlayerController::SetChatMessageString(const FString& InChatMessageString)
{
    ChatMessageString = InChatMessageString;

    // 로컬에서 직접 출력하지 않고, Server RPC를 호출하여 서버로 전달
    ServerRPC_SendChatMessage(InChatMessageString);
}

// ------------------------------------------------------------------
// 1. Server RPC Implementation (서버에서만 실행됨)
// ------------------------------------------------------------------
void ACXPlayerController::ServerRPC_SendChatMessage_Implementation(const FString& InChatMessageString)
{
    // 서버가 메시지를 받으면, 모든 클라이언트에게 Multicast RPC를 호출
    MulticastRPC_BroadcastChatMessage(InChatMessageString);
}

// ------------------------------------------------------------------
// 2. Multicast RPC Implementation (서버 + 접속된 모든 클라이언트에서 실행됨)
// ------------------------------------------------------------------
void ACXPlayerController::MulticastRPC_BroadcastChatMessage_Implementation(const FString& InChatMessageString)
{
    // 모든 클라이언트와 서버 화면에 최종 메시지 출력
    PrintChatMessageString(InChatMessageString);
}

void ACXPlayerController::PrintChatMessageString(const FString& InChatMessageString)
{
    UKismetSystemLibrary::PrintString(
        this, 
        InChatMessageString, 
        true, 
        true, 
        FLinearColor::Red, 
        5.0f
    );
}

 

1-3. 멀티플레이 구현 시 핵심 체크포인트

  • 액터 소유권 (Ownership): Server RPC는 호출하는 액터의 소유권(Owner)이 해당 Local Client에게 있을 때만 서버로 정상 전송됩니다. PlayerController는 기본적으로 접속한 로컬 클라이언트가 소유권을 가지고 있으므로 Server RPC 호출에 가장 적합한 액터입니다.
  • Reliable 키워드: 이동 데이터나 프레임 단위 동기화(예: 캐릭터 위치)는 패킷 유실을 허용하는 Unreliable을 사용하지만, 채팅/아이템 취득/데미지 계산 등 누락되면 안 되는 중요한 데이터는 반드시 Reliable로 설정합니다.
  • 입력 유효성 검증 (WithValidation): 악의적인 클라이언트가 욕설이나 허위 패킷을 보낼 수 있으므로 필요시 UFUNCTION(Server, Reliable, WithValidation)을 추가하여 ServerRPC_SendChatMessage_Validate 함수에서 텍스트 길이, 도배 여부 등을 검증한 후 true/false를 반환하도록 작성할 수 있습니다.