1. NetRole
언리얼 엔진의 네트워킹은 서버-클라이언트 모델을 기반으로 하며, 모든 액터(Actor)는 네트워크 상에서 명확한 '역할(Role)'을 가진다. 네트워크 역할(NetRole)은 특정 게임 인스턴스(서버 또는 클라이언트)가 한 액터에 대해 갖는 제어 수준 또는 권한을 정의한다. 즉, 어떤 액터가 게임 상태를 결정하는 '권위(Authority)'를 가지는지, 아니면 단순히 서버의 상태를 복제하여 '시뮬레이션'만 하는지를 결정하는 핵심적인 개념이다.
모든 네트워크 상호작용은 이 역할을 기반으로 이루어진다. 예를 들어, 플레이어의 입력을 받아 캐릭터를 움직이게 하는 권한, 서버에 특정 액션을 요청하는 권한, 프로퍼티를 변경하고 다른 클라이언트에 전파하는 권한 등이 모두 NetRole에 의해 결정된다.
2. ENetRole의 종류
ENetRole은 열거형(enum)으로, 다음과 같은 세 가지 주요 역할과 하나의 특별한 상태로 구성된다.
ROLE_Authority(권위)- 액터의 '마스터(master)' 버전. 해당 액터의 상태(위치, 프로퍼티 등)에 대한 최종 결정권을 가진다.
- 오직
Authority만이 리플리케이트(Replicated)로 지정된 프로퍼티를 변경하고, 그 변경 사항을 클라이언트의 프록시(Proxy)들에게 전파할 수 있다. - 서버-클라이언트 모델에서, 리플리케이트되는 모든 액터의
Authority는 항상 서버에 있다.
ROLE_AutonomousProxy(자율 프록시)- '원격 조종되는' 버전이지만, 어느 정도의 자율성을 가진다. 주로 클라이언트가 직접 조종하는 액터(예: 플레이어 캐릭터)에 해당한다.
- 이 역할을 가진 클라이언트는 서버로 RPC(Remote Procedure Call)를 보내 상태 변경을 요청할 수 있다. 예를 들어, 'W' 키를 눌렀다는 입력을 서버로 보내 이동을 요청할 수 있다.
- 서버의
Authority로부터 상태 업데이트를 받지만, 클라이언트 측 예측(Client-Side Prediction)을 통해 부드러운 움직임을 구현할 수 있다.
ROLE_SimulatedProxy(시뮬레이션 프록시)- '꼭두각시' 버전. 스스로 상태를 변경하거나 서버에 RPC를 보낼 권한이 거의 없다.
- 오직 서버의
Authority가 보내주는 데이터에 따라 액터의 상태를 갱신하고, 그 움직임을 보간(interpolation) 또는 외삽(extrapolation)하여 부드럽게 보여주는 역할만 한다. - 내 캐릭터가 아닌 다른 플레이어의 캐릭터, AI가 조종하는 몬스터 등이 클라이언트에서 이 역할을 가진다.
ROLE_None- 네트워크 상에서 아무런 역할을 가지지 않음을 의미. 즉, 리플리케이트되지 않는 액터다.
- 싱글플레이 게임의 모든 액터나, 멀티플레이어 게임이라도 순전히 클라이언트나 서버에만 존재하는 장식용 이펙트 등이 이 상태에 해당한다.
3. Role 과 RemoteRole
액터는 Role과 RemoteRole, 두 가지 역할 프로퍼티를 가진다. 이 두 프로퍼티는 private으로 보호되며, 각각 GetLocalRole()과 GetRemoteRole() 함수로 접근해야 한다.
GetLocalRole(): 현재 게임 인스턴스(내 컴퓨터)에서의 액터 역할을 반환한다.GetRemoteRole(): 원격 게임 인스턴스(연결된 상대방 컴퓨터)에서의 액터 역할을 반환한다.
| 위치 | 액터 | GetLocalRole() 결과 |
GetRemoteRole() 결과 |
설명 |
|---|---|---|---|---|
| 서버 | 플레이어 A의 캐릭터 | ROLE_Authority |
ROLE_AutonomousProxy |
서버는 권위를 가지며, 이 액터가 원격(클라이언트 A)에서는 자율 프록시임을 안다. |
| 클라이언트 A | 나의 캐릭터 | ROLE_AutonomousProxy |
ROLE_Authority |
클라이언트 A는 자신의 캐릭터를 조종할 자율성이 있으며, 이 액터의 권위는 원격(서버)에 있음을 안다. |
| 클라이언트 B | 플레이어 A의 캐릭터 | ROLE_SimulatedProxy |
ROLE_Authority |
클라이언트 B에게 플레이어 A의 캐릭터는 단순 시뮬레이션 대상이며, 이 액터의 권위는 원격(서버)에 있음을 안다. |
이처럼 GetLocalRole()은 현재 내 컴퓨터에서의 권한을 체크하는 데 사용되며 (if (GetLocalRole() == ROLE_Authority) 와 같은 분기 처리), GetRemoteRole()은 상대방의 역할을 알아야 할 때 사용된다.
4. 역할과 액터 복제 흐름
- 프로퍼티 복제 (Property Replication): 데이터는 항상
Authority에서 프록시들(AutonomousProxy,SimulatedProxy)로 흐른다. 서버가 캐릭터의 체력을 100에서 90으로 바꾸면, 이 변경 사항이 모든 클라이언트에게 전송되어 캐릭터의 체력이 90으로 업데이트된다. 클라이언트가 임의로 체력을 120으로 바꿔도 이는 서버에 반영되지 않으며, 다음 번 서버의 복제 데이터에 의해 다시 90으로 덮어쓰여진다. - RPC (Remote Procedure Call): 함수 호출은 특정 방향으로만 가능하다.
Client-to-Server:AutonomousProxy는 서버의Authority에게 RPC를 보낼 수 있다. (UFUNCTION(Server))
대표적인 예로 플레이어가 총을 쏘고 싶을 때, 클라이언트의AutonomousProxy가 서버의Authority에게 '총을 쏘겠다'고 요청하는 것이 있다.Server-to-Client:Authority는 프록시들에게 RPC를 보낼 수 있다. (UFUNCTION(Client, NetMulticast))
예시로 서버가 모든 클라이언트에게 '게임이 시작되었다'는 이벤트를 보내거나, 특정 클라이언트에게만 '개인적인 UI를 띄워라'고 명령하는 것 등이 있다.
5. 내부 구현 및 계층 구조
- 게임플레이 프레임워크 계층 (Gameplay Framework Layer)
- 플레이어가 게임에 접속하면, 서버의
AGameModeBase는 해당 플레이어를 위한APlayerController를 생성한다. AGameModeBase는 로그인 로직을 거쳐 플레이어가 조종할APawn(또는ACharacter)을 스폰하고,APlayerController::Possess()함수를 호출하여 폰에 빙의시킨다.
- 플레이어가 게임에 접속하면, 서버의
- 엔진 - 소유권 및 연결 계층 (Engine - Ownership & Connection)
AActor::SetOwner():Possess과정에서 폰의 소유자(Owner)는APlayerController로 설정된다. 이것이 역할 결정의 핵심이다. 액터의 소유자가APlayerController이고, 그APlayerController가 특정 클라이언트 연결(UNetConnection)과 연결되어 있다면, 해당 클라이언트는 그 액터에 대해AutonomousProxy역할을 갖게 된다.UNetConnection: 서버와 클라이언트 간의 네트워크 연결을 나타내는 객체다. 서버는 각 클라이언트에 대한UNetConnection을 가지고 있다.
- 엔진 - 리플리케이션 시스템 계층 (Engine - Replication System)
UActorChannel생성: 서버가 클라이언트에 새로운 액터를 복제해야 할 때, 둘 사이에UActorChannel을 연다.- 역할 결정 로직: 채널이 열릴 때, 서버는 이 액터의 소유 관계를 확인한다.
Actor->GetOwner()가UNetConnection의 소유 액터(Connection->OwningActor, 즉PlayerController)와 일치하는지 검사한다. - 만약 일치한다면, 서버는 이 클라이언트에게 해당 액터의 역할을
ROLE_AutonomousProxy로 지정하여 내려보낸다. - 일치하지 않는다면,
ROLE_SimulatedProxy로 지정한다. - 서버 자신은 항상
ROLE_Authority를 유지한다. - 이 역할 정보는 액터가 처음 복제될 때 클라이언트로 전송되어 클라이언트 측 액터의
LocalRole이 설정된다.
6. 요약
NetRole, 즉 네트워크 역할은 특정 액터에 대해 서버와 클라이언트가 갖는 권한 수준을 정의하는 핵심 개념입니다. 세 가지 주요 역할이 있습니다.
첫째, ROLE_Authority (권위)는 액터의 상태를 최종적으로 결정하는 마스터 버전으로, 서버에만 존재합니다. 프로퍼티 변경과 복제를 책임집니다.
둘째, ROLE_AutonomousProxy (자율 프록시)는 플레이어가 직접 조종하는 캐릭터처럼, 클라이언트 측에서 입력을 받아 서버로 RPC를 전송할 수 있는 권한을 가진 프록시입니다.
셋째, ROLE_SimulatedProxy (시뮬레이션 프록시)는 다른 플레이어나 AI처럼, 서버가 보내주는 상태를 받아 보여주기만 하는 수동적인 프록시입니다.
이러한 역할 구분을 통해 언리얼 엔진은 누구의 데이터가 최종본인지, 그리고 데이터가 어디서 어디로 흘러야 하는지를 명확히 하여 복잡한 멀티플레이어 환경을 체계적으로 관리합니다.
'Unreal' 카테고리의 다른 글
| Gameplay Framework (0) | 2025.10.27 |
|---|---|
| Remote Procedure Call (0) | 2025.10.27 |
| Replication Condition (0) | 2025.10.24 |
| 언리얼 엔진 리플리케이션 Replication (1) | 2025.10.24 |
| 언리얼 엔진 리플렉션 시스템 Unreal Engine Reflection System (0) | 2025.10.23 |
