[2025-03-13] 언리얼 네트워크와 객체 통신 이해하기

하돌·2025년 3월 13일
0

네트워크

목록 보기
2/5

몇 일전부터 다시 새로운 게임 프로젝트를 만들기 위해 그 기초가 되는 네트워크를 배우기 시작했다. 이번에는 그 게임이 멀티 플레이어 게임이기 때문에 네트워크를 배우는 것이 중요하다.

아래 같은 목표 달성을 위해 강의자료와 강의에서 나온 핵심 단어들을 나의 말로 다시 재정리해보았다.

목표

  • 언리얼 엔진의 네트워크 RPC 호출과 브로드캐스팅을 이해
  • 언리얼 엔진의 네트워크 Listen / Dedicate 서버의 차이를 이해
  • 언리얼 에디터에서 Listen Server 환경을 구성하고 채팅을 구현

네트워크 핵심 단어 정리

Replication

언리얼로 채팅 구현하기가 목표인데 그러려면 네트워크가 필요하다.
그런 네트워크를 구현하는데 필수적인 Replication이 뭔지 알아야 한다.
그리고 어떻게 해야 올바른 접근이 가능한 지에 대해 알야야 한다.

언리얼의 엔진에서 Replication이란

Network Framework API를 상속받아 구현한 구현체이다.

출처: https://unrealcommunity.wiki/unreal-schematics-2d6859
ㄴ 해당 출처 사이트의 UNREAL ENGINE PROGRAMMING PIPELINE에서 확인할 수 있다.

위 사진에서 주로 쓰고 알아야 될 개념은 3가지이다.
RPCs, Actor Replication, RepNotify

위 사진에서 크게 2가지 부분으로 나눠서 생각하면 된다.

  • RPCs, Reliability, RepNotify
    ㄴ 여기서는 RPC와 Notify를 한다고 생각하자

  • Ownership, Property Replication, Actor Replication
    ㄴ 여기서는 최종적으로 Actor Replication을 한다고 생각하자.

Property Replication

Unreal Engine에서 네트워크를 통해 객체의 속성(변수) 값을 클라이언트에 동기화하는 기능이다.
즉, Property Replication이 돼야 서버와 클라이언트의 액터가 위치, 회전, 체력값 등을 동일하게 유지할 수 있다.

Actor Replication

게임에서 액터의 이동, 회전 등은 Actor Replication을 통해 자동으로 동기화된다.
클라이언트가 서버에 액터 스폰을 요청하면, 서버에서 생성된 액터가 클라이언트에도 복제(Replicate)되어 동기화된다.

서버에 있는 값이 변경되면 Replication(복제)이 일어나는데
서버->클라이언트로 값을 넘겨주는 역할이다.

서버에서 복제가 일어나면 클라이언트의 이벤트 함수가 자동으로 호출한다.
이때 자동으로 호출되는 부분은 누가 알려주는 지 궁금해서 LLM(Large Langauage Model)의 도움을 받았다.

Unreal Engine의 Replication 시스템이 자동으로 복제된 값을 받아서 클라이언트에 그 값을 전달한다.
클라이언트는 그 값을 받으면 이벤트 함수를 호출하는 것이다.

즉, 클라이언트의 이벤트 함수가 자동으로 호출되는 이유는
리플리케이션 시스템이 서버의 값이 변경되었을 때 그걸 인지해서 자동으로
클라이언트 내부의 이벤트 함수를 호출하기 때문이다.

RepNotify

  • 서버에서 클라이언트로 값이 복제될 때, 관련 이벤트 함수를 자동으로 호출한다.
  • 말그대로 Replication이 되면 Notify를 해준다.
    ㄴ 번역하면 서버->클라이언트로 값이 복제가 되면 그걸 복제됐다고 알림해주는 것이다.

RPC(Remote Procedure Call)

  • 서버와 클라이언트가 서로 원격으로 함수를 호출할 수 있게 해주는 시스템이다.
  • RPC를 사용하면 서버 → 클라이언트, 클라이언트 → 서버로 함수를 실행할 수 있지만,
    이를 위해 수동으로 호출하는 코드를 작성해야 한다.
  • 즉, 서버와 클라이언트 간 동기화가 필요할 때 반드시 필요한 시스템이다.
UFUNCTION(Server, Reliable)
void ServerFireWeapon();

UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayExplosionEffect();
  • Reliable, Unreliable 선택이 가능하다.

Reliable

  • 쉽게 말해, "데이터를 확실하게 받았는지 확인하는 TCP 방식"이라고 보면 된다.
  • 데이터가 제대로 수신되지 않으면, 다시 전송하여 확실하게 전달을 보장한다.
  • 이 과정 때문에 속도가 빠른 UDP보다 느릴 수밖에 없다.

Unreliable

  • 쉽게 말해, "수신 확인 없이 그냥 보내는 UDP 방식"이라고 보면 된다.
  • 데이터가 도착했는지 확인하지 않고, 빠르게 송신만 한다.
  • 속도가 빠르지만, 데이터 유실(패킷 손실)이 발생할 수 있다.
  • 예를 들어, 총을 쐈을 때 파티클 효과가 나와야 한다. 근데 그게 게임 시스템을 유지하는데에 영향이 없으니 꼭 전달할 필요는 없다. 그럴때 Unreliable을 쓸 수 있다.

강의를 하신 분은 Reliable 방식으로 먼저 개발을 하다가
최적화 단계에서 하나하나씩 Unreliable로 바꿔보는 방식을 추천했다.
왜냐하면 처음부터 Unrelaible로 하면 데이터를 받았는지 안 받았는지 검증이 안되니까.. 그렇다.


게임에서 서버란 사용자의 데이터를 저장하는 기능 외에 게임의 심판 역할을 하는 로직 전체를 이야기한다.

언리얼에서 네트워크 멀티플레이를 구현하는 방법은 언리얼 외에도 소켓 통신, Restful API 등 많은 방식이 있지만, 언리얼이 기본적으로 제공하는 Listen ServerDedicated Server에 대해서 알아보았다.

Dedicated Server(전용 서버)

  • 데디케이트 서버 같은 경우 16 vs 16, 32 vs 32처럼 정해진 숫자의 플레이어들이 대전하는 게임 서버로 많이 사용되었다.
  • Dedicated는 특정 목적의, 전용의 << 같은 의미로 해석할 수 있다.
  • 게임사에서 관리하는 서버라고 보면 된다.
  • 별도의 빌드가 필요하며, 클라이언트 기능을 포함하지 않는다.
  • 보안 측면에서 좋다.
  • 서버가 종료되지 않으므로 유저 데이터나 게임 상태를 지속적으로 DB(데이터 저장소)에 저장 가능하다.

Listen Server

  • Lan 파티 플레이 게임할때 게임 서버로 사용된다.
  • 클라이언트 중 하나가 방(게임 서버)을 만들어서 거기에 친구들 초대해서 플레이하는 게임을 스팀에서 많이 보았을 것이다. 그것이 바로 리슨 서버다.
  • 빌드가 필요 없고, 클라이언트 기능을 포함한다.
  • 클라이언트와 서버의 기능이 합쳐져 있으므로 두 개를 구분할 권한 체크가 필수다.
  • 로컬 서버에서 코드를 뜯어서 막 데이터를 조작하면 무한 자원을 쓰는 등의 방식으로 해킹이 되기 때문에 보안에 취약하다.

언리얼에서 BP_Controller 내부에 이런 커스텀 이벤트를 만들었다고 가정해보자. 이렇게 생성한
이벤트의 Replicates 속성을 Multicast, Run on Server , Run on owning Client로 설정하면,
그 이벤트는 RPC가 된다.

Not Replicated

  • 싱글플레이 전용, 네트워크에 전파되지 않음.

Multicast

  • 서버가 모든 클라이언트에게 브로드캐스팅 (예: 게임 시작, 폭발 효과).

Run on Server

  • 클라이언트가 요청하면 서버에서만 실행됨 (예: 공격, 점수 업데이트).
  • 클라이언트에서 바로 호출할 수 없다.

Run on owning Client

  • 서버가 특정 클라이언트에게만 RPC 호출을 보냄 (예: UI 업데이트).
profile
게임 개발자로서 배운 것을 정리한 블로그입니다. 벨로그 서버가 불안정한 거 같아서 티스토리로 옮겼습니다.

0개의 댓글