Unreal 게임 개발 과정 TIL

Today's I Learning

개인 공부

07.28 키워드로 개념 정리) Client/Server구조

Sunlight__ 2026. 7. 28. 22:00

1. Client/Server

UE5의 멀티플레이어 시스템은 데디케이티드 서버(Dedicated Sever) 기반의 클라이언트-서버(Client-Sever) 아키텍쳐를 표준으로 사용한다.

게임 세션의 단 하나의 서버만이 "진실(Truth)"을 쥐고 있으며, 클라이언트는 서버가 전송해 주는 상태를 시각적으로 보여주고 플레이어의 입력을 서버로 전달하는 역할을 한다.

 

1) 핵심 개념 : 권한(Authority)과 복제(Replication)

- 언리얼 엔진의 네트워크를 이해하려면 다음 두 가지 개념이 가장 중요하다.

  • 권한 (Authority)
    • 서버는 게임 내 모든 데이터와 로직에 대해 최종 결정권을(Authority)를 가진다.
    • 예 : "플레이어가 총을 쐈을 때 맞았는가?", "체력이 0이 되었는가?" 등은 서버가 판단한다.
  • 복제 (Replication)
    • 서버에서 일어난 상태 변화(변수 값 변경, 액터 생성/파괴 등)를 연결된 클라이언트들에게 동기화(복사)하는 과정이다.
    • 복제는 기본적으로 [ 서버 -> 클라이언트 ] 단방향으로만 흐른다.

2) UE5 서버의 형태

- UE5 멀티플레이어 서버는 크게 두 가지 방식으로 운영된다.

서버 종류 특징 및 설명  주요 사용처
데디케이티드 서버
(Dedicated Sever)
- 렌더링(화면출력) 및 사운드 기능이 제거된 순수 로직 전용 서버이다.

- 플레이어로 참여하지 않는 독립된 서버 프로세스로 동작한다.

- 치트 방지에 유리하고 가장 안정적이다.
- 배틀그라운드, Valolant,
MMORPG, 경쟁형 멀티플레이
리슨 서버
(Listen Sever)
- 호스트(방장) 역할을 하는 플레이어의 클라이언트가 서버 역할도 겸임한다.

- 서버 구축비용이 들지 않지만, 방장의 네트워크 환경에 세션 전체가 영향을 받는다.
- 4인 코옵(Co-op) 게임,
소규모 캐주얼 게임

 

3) 통신 매커니즘 : RPC (Remote Procedure Call)

서버에서 클라이언트로의 변수 복제만으로는 게임을 진행할 수 없다.
클라이언트의 입력 (예 : 이동, 공격 버튼 클릭)을 서버에 전달하거나, 특정 이벤트를  호출하기 위해 RPC(원격 프로시저 호출)를 사용한다.

C++ 코드에서는 UFUNCTION 매크로 스펙파이어를 통해 지정한다.
// 1. Client -> Sever (Sever RPC)
// 클라이언트가 서버에게 실행을 요청 (예: 공격 버튼 누름)
UFUNCTION(Sever, Reliable)
void Sever_Attack():

// 2. Sever -> Specific Client (Client RPC)
// 서버가 특정 클라이언트에게만 실행을 명령 (예: UI 업데이트, 퀘스트 완료 알림)
UFUNCTION(Client, Reliable)
void Client_UpdateHUD(int32 NewScore);

// 3. Sever -> All Clients (NetMulticast RPC)
// 서버가 접속된 모든 클라이언트에게 실행을 명령 (예: 폭발 이펙트 재생, 사운드 출력)
UFUNCTION(NetMulticast, Unreliable)
void Multicast_PlayExplosionFX();

 

💡Reliable vs Unreliable

  • Reliable (신뢰성 있음) : 패킷 손실 시 재전송하여 반드시 도착을 보장한다. (예 : 아이템 구매, 공격 요청)
  • Unreliable (신뢰성 없음) : 패킷이 손실되어도 재전송하지 않는다. 매 프레임 전송되거나 경미한 연출에 사용한다. (예 : 이동 입력, 시각적 이펙트)

4) 네트워크 프레임워크 클래스 구조

UE5 프레임워크 클래스들은 서버와 클라이언트에 존재할 수 있는 범위(존재성)가 다르다.
이 구조를 파악하는 것이 멀티플레이어 개발의 시작이다.
  • GameMode : 서버에만 존재하며, 게임의 규칙(승리 조건, 스폰 로직 등)을 관리한다.
    클라이언트는 GameMode에 접근할 수 없다.
  • GameState : 서버와 모든 클라이언트에 존재한다. 게임 전체 상태(남은 시간, 현재 스코어 등)를 공유할 때 사용한다.
  • PlayerController : 플레이어의 입력을 처리한다. 서버에는 모든 플레이어의 Controller가 존재하지만, 클라이언트에는 자기 자신의 Controller만 존재한다.
  • PlayerState : 플레이어 개인의 공유 정보(이름, 핑, 킬/데스 등)를 저장하며, 모든 클라이언트에 복제된다.
  • Pawn / Character : 월드에 배치된 플레이어의 분신으로, 모든 클라이언트에 복제되어 눈에 보이게 된다.

5) 네트워크 지연 극복 : 예측과 보정 (Prediction & Reconciliation)

네트워크 전송에는 언제나 시차(Ping/Latency)가 존재한다. 내가 이동 키를 눌렀을 때 서버의 승인을 기다린 후 움직인다면 게임이 매우 둔하게 느껴질 것이다.

UE5의 CharacterMovementComponent는 이를 해결하기 위한 강력한 클라이언트 측 예측(Client-side Prediction) 기능을 기본적으로 탑재하고 있다.
  1. 클라이언트 즉시 이동 : 플레이어가 이동 입력 시, 서버의 응답을 기다리지 않고 로컬에서 먼저 캐릭터를 이동시킨다.
  2. 서버 검증 : 이동 입력 기록(Input/Timestamp)을 서버로 전송한다. 서버는 이 이동이 유효한지 검증한다.
  3. 위치 보정 (Reconciliation) : 만약 서버가 계산한 위치와 클라이언트의 위치가 크게 다르면 (예 : 벽에 부딪힘, 핵 사용 등), 서버가 클라이언트의 위치를 강제로 되돌린다(Snap/Smoothadjustment).