unreal 8기

2026-6-9 TIL

왕건 2026. 6. 9. 20:57

TIL: Unreal Engine 서버-클라이언트 구조와 Replication 이해하기

 

오늘 배운 내용

오늘은 Unreal Engine의 멀티플레이 구조에서 서버와 클라이언트가 어떤 방식으로 연결되는지 배웠다.

처음에는 PlayerCharacter, PlayerController, PlayerState는 서버에서 클라이언트로 복제되는 것처럼 보이는데, Level은 왜 점선으로 표시되지 않는지 궁금했다.

정리해보면 Level은 서버에서 클라이언트로 복제되는 객체라기보다는, 클라이언트가 같은 맵 파일을 로컬에서 여는 개념에 가깝다.

서버는 클라이언트에게 어떤 Level에 접속해야 하는지 알려주고, 클라이언트는 자신이 가지고 있는 같은 Level을 로드한다.

그 후 서버는 그 Level 안에서 필요한 Actor들의 생성과 상태를 클라이언트에게 복제한다.

 

1. Level은 복제되는 것이 아니라 로드된다

Unreal 멀티플레이에서 서버와 클라이언트는 같은 Level을 기준으로 게임을 진행한다.

하지만 서버가 Level 파일 자체를 클라이언트에게 보내는 것은 아니다.

Server
-> 이 맵으로 접속해라

Client
-> 내 PC에 있는 같은 맵을 연다

이런 흐름에 가깝다.

그래서 Level은 PlayerCharacter나 PlayerState처럼 서버에서 생성된 인스턴스가 클라이언트에 복제되는 대상이라고 보기 어렵다.

Level은 클라이언트가 직접 로드하고, 그 안에서 움직이는 Actor들의 상태를 서버가 맞춰주는 방식이다.

 

2. Replication이란 무엇인가

Replication은 서버가 가진 Actor의 상태를 클라이언트에도 전달해서 비슷하게 유지하는 기능이다.

예를 들어 서버에 캐릭터가 있다고 하면 다음과 같은 정보가 있을 수 있다.

Server Character
- 위치
- 회전
- 체력
- 닉네임

이 중 Replicated로 설정된 값들은 클라이언트에도 전달된다.

Client Character
- 서버에서 받은 위치
- 서버에서 받은 회전
- 서버에서 받은 체력
- 서버에서 받은 닉네임

즉, Replication은 메모리를 통째로 복사하는 것이 아니다.

서버가 원본이고, 클라이언트는 서버가 보내주는 상태를 받아서 자기 화면에 반영하는 것이다.

Actor를 복제하려면 보통 다음과 같이 설정한다.

bReplicates = true;

변수도 복제 대상으로 만들 수 있다.

UPROPERTY(Replicated)
int32 HP;

이렇게 하면 서버에서 HP 값이 바뀌었을 때 클라이언트에도 그 값이 전달될 수 있다.

 

3. 클라이언트는 서버보다 늦을 수밖에 없다

Replication은 네트워크를 통해 전달된다.

그래서 클라이언트 입장에서는 서버보다 조금 늦게 상태를 알게 된다.

Server에서 상태 변경
-> 네트워크 전송
-> Client가 수신
-> Client 화면에 반영

이 과정이 있기 때문에 원리상 지연은 생길 수밖에 없다.

하지만 게임에서는 이 지연을 그대로 보여주지 않기 위해 여러 보정 방식을 사용한다.

내 캐릭터 움직임은 Client Prediction으로 먼저 움직인 것처럼 보여준다.

그리고 나중에 서버가 정확한 위치를 알려주면 Server Reconciliation으로 조용히 보정한다.

다른 플레이어의 움직임은 Interpolation을 통해 뚝뚝 끊기지 않게 부드럽게 보여준다.

즉, 실제로는 약간 늦지만 사람이 느끼기 어렵게 처리하는 것이다.

 

4. 클라이언트끼리 직접 통신하지 않는 이유

Unreal의 서버-클라이언트 구조에서는 클라이언트끼리 직접 통신하지 않는다.

Client A가 Client B에게 직접 명령을 보내는 구조가 아니라, 항상 서버를 거친다.

Client A
-> Server
-> Client B

이렇게 하는 이유는 서버가 게임의 진짜 상태를 관리해야 하기 때문이다.

클라이언트는 사용자 PC에서 실행되기 때문에 조작될 가능성이 있다.

만약 클라이언트가 다른 클라이언트에게 직접 말할 수 있다면 다음과 같은 문제가 생길 수 있다.

Client A
-> 나는 총을 맞췄어
-> 너는 HP가 줄어야 해
-> 내 위치는 사실 여기야
-> 내 돈은 999999야

이런 말을 다른 클라이언트가 그대로 믿으면 치트에 매우 취약해진다.

그래서 클라이언트는 서버에게 요청만 하고, 실제 판정은 서버가 한다.

Client
-> 공격 버튼을 눌렀습니다

Server
-> 실제로 맞았는지 검사
-> 맞았으면 HP 감소
-> 결과를 클라이언트들에게 전달

이 구조 덕분에 서버가 권위 있는 판정자가 될 수 있다.

 

5. GetNetConnection의 의미

오늘 또 헷갈렸던 부분은 GetNetConnection이었다.

GetNetConnection은 직접 통신을 실행하는 함수라기보다는, 이 Actor가 어느 클라이언트와 연결되어 있는지 찾는 함수에 가깝다.

Actor는 보통 자기 자신이 네트워크 연결 정보를 직접 가지고 있지 않다.

그래서 Owner를 따라가며 연결 정보를 찾는다.

Actor
-> Owner에게 물어봄

Pawn
-> Controller가 있으면 Controller에게 물어봄

PlayerController
-> 실제 Player가 있으면 NetConnection을 반환함

예를 들어 구조가 다음과 같다고 하면

PlayerController
-> Character
-> Weapon Actor

Weapon Actor는 직접 클라이언트 연결 정보를 모른다.

그래서 Owner를 따라 Character에게 물어보고, Character는 Controller에게 물어보고, 최종적으로 PlayerController가 NetConnection을 알려준다.

이 과정을 통해 Unreal은 이 Actor가 어느 클라이언트에게 소유된 Actor인지 알 수 있다.

그래서 Client RPC를 보낼 때도 어느 클라이언트에게 보내야 하는지 판단할 수 있다.

 

오늘 헷갈렸던 점

처음에는 PlayerCharacter, PlayerController, PlayerState가 클라이언트에 생기니까 Level도 똑같이 복제되는 줄 알았다.

하지만 Level은 복제되는 Actor라기보다는 클라이언트가 직접 로드하는 맵이다.

그리고 Replication은 객체를 통째로 복사하는 것이 아니라, 서버의 Actor 상태를 클라이언트에 동기화하는 것이다.

또 클라이언트끼리 직접 통신하지 않는 이유도 처음에는 단순한 구조 제한처럼 보였지만, 실제로는 치트 방지와 서버 권위 유지가 가장 큰 이유였다.

 

오늘의 핵심 정리

  1. Level은 서버에서 클라이언트로 복제되는 것이 아니라, 클라이언트가 같은 맵을 로드한다.
  2. 서버는 Level 안의 Actor 생성과 상태를 Replication으로 클라이언트에게 전달한다.
  3. Replication은 서버 상태를 클라이언트 화면에 맞춰 보여주기 위한 기능이다.
  4. 클라이언트는 네트워크 지연 때문에 서버보다 조금 늦을 수밖에 없다.
  5. 게임은 Client Prediction, Server Reconciliation, Interpolation으로 지연을 자연스럽게 숨긴다.
  6. 클라이언트끼리는 직접 통신하지 않고 항상 서버를 거친다.
  7. 서버가 최종 판정을 해야 치트와 상태 불일치를 막을 수 있다.
  8. GetNetConnection은 Actor가 어느 클라이언트 소유인지 찾는 데 사용된다.

정리하면 Unreal 멀티플레이에서 서버는 원본 상태를 가진 권위자이고, 클라이언트는 서버가 알려주는 정보를 받아 화면에 보여주는 역할을 한다.

Level은 클라이언트가 직접 로드하지만, 그 안에서 움직이는 Actor들의 상태는 서버 기준으로 복제된다.

오늘 내용을 통해 서버-클라이언트 구조, Replication, 클라이언트 지연, NetConnection의 역할을 조금 더 쉽게 이해할 수 있었다.

'unreal 8기' 카테고리의 다른 글

2026-6-11 TIL  (0) 2026.06.11
2026-6-10 TIL  (0) 2026.06.10
2026-6-4 TIL  (0) 2026.06.04
[7번 과제] Pawn 클래스 3D캐릭터 만들기  (0) 2026.04.16
[6번 과제] 회전발판과 움직이는 장애물  (0) 2026.04.09