P2P Server(Peer to Peer Server) -> 각각의 컴퓨터가 클라이언트이자 서버인 구조
Listen Server -> 클라이언트이자 서버인 방장(Host)이 있고, 나머지 참가자(Guest)는 모두 클라이언트 역할만 맡는 형태. (P2P의 일종이라고 볼 수 있음)
Dedicated Server -> 서버를 담당하는 컴퓨터가 따로 있음. 서버-클라이언트 구조.
Dedicated Server의 실행 흐름도
1. 서버 실행과 레벨 오픈
PIE든 Server.exe든, 서버 프로그램이 실행됨
실행 시 Open {Level이름}?Listen 인자가 전달됨
- Open {Level이름} - 해당 레벨이 열림
- ?Listen - 이 옵션 덕분에 다른 컴퓨터의 접속이 가능해짐 (리슨 서버가 됨)
레벨에는 WorldSettings가 있고, 여기 설정된 GameMode/GameState 정보를 바탕으로 서버가 GameMode와 GameState 액터를 생성함
2. GameMode = 서버 그 자체
가장 중요한 포인트
GameMode 액터는 전체 네트워크에서 오직 서버 한 곳에만 존재함
클라이언트에는 GameMode가 복제되지 않고 존재 자체가 없음
그래서 GameMode가 곧 서버를 대변한다고 봐도 무방함
3. Client1 접속 과정
- 클라이언트가 서버의 IP주소와 포트번호로 접속을 시도함
- 서버는 열어둔 Level 정보를 클라이언트에게 넘김
- 클라이언트도 해당 Level을 열고, 성공했다고 서버에게 알림
- Level 오픈에 성공한 Client1 전용 PlayerState, PlayerController, PlayerCharacter가 서버에 생성됨
- 이것이 다시 Client1에 복제됨
- GameState도 함께 복제됨
4. Client2 접속 과정
Client1과 동일한 흐름이 반복됨
- 다른 클라이언트가 접속을 시도함
- 서버가 Level 정보를 넘김
- 클라이언트가 Level을 열고 성공을 알림
- Client2 전용 PlayerState, PlayerController, PlayerCharacter가 서버에 생성됨
- Client2에 복제됨
- GameState도 복제됨
이때 Client1과 Client2의 PlayerState, PlayerCharacter도 서로에게 복제되면서, 두 클라이언트가 서로를 보게 됨

서버-클라이언트 구조의 핵심 특징
클라이언트와 클라이언트 간의 직접 통신은 불가능함
오직 서버와 클라이언트 사이의 통신만 가능함
모든 정보는 반드시 서버를 거쳐서 전달됨 (Client1 → Server → Client2 방식)
이 원칙이 앞으로 배울 RPC나 프로퍼티 레플리케이션 설계에 그대로 영향을 줌
- GameMode = 판정을 내리는 심판 역할 : 플레이어 접속 처리, 승패 판정, 리스폰 로직, 룰 적용 같은 로직/권위(authority) 처리. 보안상 클라이언트한테 줄 필요 없고(치트 방지), 판정 과정 자체는 안 보여줘도 됨.
- GameState = 전광판 역할 : 현재 스코어, 남은 시간 같은 모든 플레이어가 화면에 표시해야 할 정보. 클라이언트 UI에 띄워야 하니 복제 필수.
- PlayerState: 점수, 이름 같은 공개 정보
- PlayerController: 플레이어의 입력(키보드/마우스)을 처리하는 조종 장치
- PlayerCharacter(Pawn): 게임 월드 안에서 실제로 보이는 캐릭터 몸
이 세 액터는 서버 메모리에 생성되지만 복제(Replication)를 통해 해당 클라이언트 컴퓨터에도 똑같이 복사됨.
- PlayerController: 자기 자신의 클라이언트에게만 복제. 다른 사람의 컨트롤러가 내 컴퓨터에 복제되면 다른 사람 캐릭터를 조종할 수 있게 되는 보안 문제 발생
- PlayerState, PlayerCharacter: 모든 클라이언트에게 복제 (다른 플레이어들도 보여야 하고 정보를 알아야 하므로)
- 서버 → 클라이언트: Property Replication (변수 값이 바뀌면 자동 복제) 또는 Client RPC (Client_ 접두사 함수)
- 클라이언트 → 서버: Server RPC (Server_ 접두사 함수)
클라이언트 A가 점프했을 때 클라이언트 B 화면에도 보이게 하려면?
- 클라이언트 A → 서버: A가 점프 키를 누르면 A의 PlayerController가 Server RPC를 호출해서 "점프했어요"라고 서버에 알림
- 서버 처리: 서버가 요청을 받아 판단하고, A의 PlayerCharacter 상태(애니메이션, 위치 등)를 실제로 변경
- 서버 → 모든 클라이언트(A, B 포함): 변경된 상태가 Property Replication을 통해 자동으로 모든 클라이언트에 복제 → B의 화면에서도 A의 점프가 보이게 됨
IsLocalController() 함수를 활용한 내 컴퓨터 확인
// CXPlayerController.cpp
...
void ACXPlayerController::BeginPlay()
{
Super::BeginPlay();
if (IsLocalController() == false)
{
return; // 내 컴퓨터가 아니라면, 아래 CreateWidget() 함수 호출을 막음.
}
...
}
...
'학습 > Unreal' 카테고리의 다른 글
| NetRole (Authority, Proxy, 로컬/리모트 롤) (0) | 2026.06.19 |
|---|---|
| NetMode, NetConnection, NetDriver, Ownership (0) | 2026.06.18 |
| TArray, TMap, TSet 사용해서 가방에 아이템 담기 (0) | 2026.06.09 |
| TObjectPtr / TSubclassOf / TArray / TSet / TMap - 언리얼 주요 타입과 컨테이너 정리 (0) | 2026.06.04 |
| 언리얼 접두사 규칙과 모듈 구조 (1) | 2026.06.02 |
