액터의 역할

언리얼 엔진의 네트워크 프레임워크는 기본적으로 서버/클라이언트 모델을 기준으로 만들어졌다.

 

서버는 클라이언트의 최신 상태를 유지하기 위해 액터를 사용한다. 서버가 특정 클라이언트를 업데이트할 때, 지난 업데이트 시점 이후 변경되었다고 보는 연관 액터를 수집한 다음, 액터의 최신 상태를 유지하기에 충분할 만큼의 정보를 클라이언트에 전송한다.

 

네트워크 모드 유형

NM_Standalone

ㄴ 로컬 머신에서 실행되며 원격 머신에서 클라이언트를 받지 않는 서버 (싱글 플레이어, 로컬 멀티플레이 게임에 적합)

 

NM_DedicatedServer

ㄴ 로컬 플레이어가 없어 사운드, 그래픽, 사용자 입력, 기타 플레이어 관련 기능을 제거하여 보다 효율적인 실행이 가능한 전용 서버. 신뢰 서버에서 호스팅되는 멀티플레이어 게임에 사용되며 경쟁형 MOBA, MMO, 온라인 슈팅 게임 등 퍼포먼스와 신뢰성이 중요한 서버가 필요한 경우에 사용

 

NM_ListenServer

ㄴ 로컬 플레이어가 있는 서버, 사용자는 써드 파티 서버 없이 게임을 구성하여 플레이할 수 있음. 호스트에 네트워크 지연시간이 없어 호스트 플레이어에게 약간 유리하게 적용될 수 있음.

 

NM_Client 

ㄴ 서버가 아닌 유일한 모드. 데디케이티드 또는 리슨 서버로 접속되는 클라이언트

 

서버의 역할

게임플레이 흐름의 구동을 담당 (서버의 GameMode 액터를 통해 구동되고, GameMode액터의 중요한 상태를 GameState 액터에 반영하면, GameState가 각 클라이언트에 리플리케이트)

ㄴ 새 맵으로 이동할 때가 되었음을 클라에게 알리기

ㄴ 액터의 리플레케이션

 

접속 프로세스 예시

1. 클라가 서버에 접속요청

2. 서버가 수락하면 현재 맵을 전송

3. 서버는 클라가 맵을 로드할 때까지 기다림

4. 로드 이후 AGameModeBase::PreLogin을 호출

ㄴ 서버에 접근 시도중인 플레이어를 수락 또는 거부할 수 있음

5. 수락되면 서버는 AGameModeBase::Login을 호출

ㄴ 새로운 PlayerController를 만들고 새로 접속된 클라이언트에 리플리케이트 시킨다. 클라이언트의 접속 과정에서 임시로 사용하고 있던 PlayerController를 대체한다.

ㄴ APlayerController::BeginPlay가 호출된다.

6. AGameModeBase::PostLogin이 호출된다. 이후 서버가 PlayerController에서 RPC 함수 호출을 시작해도 안전하다.

 

캐릭터의 레플리케이션

네트워크 환경에서 캐릭터는 캐릭터가 가지는 Character Movement 컴포넌트 때문에 레플리케이션된다. (클라이언트-서버 네트워킹이 자동으로 탑재되어 있다.)

 

개발자는 네트워크 Movement를 커스텀하기 위해 Character Movement 컴포넌트를 프레임워크로써 사용할 수도 있다.

 

Character Movement 컴포넌트의 TickComponent 함수에서는 PerformMovement 함수를 호출하여 플레이어의 input에 따른 예상 가속도를 계산한 뒤에 최종 움직임을 캐릭터에 적용한다. PerformMovement에서는 movement 종류(걷기, 떨어지기) 에 따라 다른 물리 함수를 적용하여 움직임을 계산한다.

 

네트워크를 사용하지 않는 환경에서는 PerformMovement가 틱마다 직접적으로 호출되지만 네트워크 게임에서는 다른 함수들에 의해 간접적으로 호출된다.

 

Network Role

Character Movement 컴포넌트는 이 컴포넌트를 소유하는 캐릭터의 network role에 따라 어떻게 replicate할지를 결정한다.

 

1. Autonomous Proxy

ㄴ 클라이언트의 플레이어가 조종하는 캐릭터

 

2. Authority

ㄴ 서버에서 존재하는 캐릭터

 

3. Simulated Proxy

ㄴ 클라이언트에 존재하는데 AI나 다른 클라이언트에 의해 조종되는 캐릭터

 

Movement Replication 정리

1. TickComponent 함수에서는 프레임에 대한 가속도 및 회전 변화를 계산하고, 로컬 제어 캐릭터의 경우 PerformMovement, 네트워크 클라이언트의 경우 ReplicateMoveToServer를 호출하여 이동을 캐릭터에 적용한다.

 

2. ReplicateMoveToServer 함수는 이동 대기목록(PendingMove list)에 이동을 저장하고 PerformMovement를 호출하여 ServerMove에 movement 파라미터, 클라이언트 액터의 결과 위치, 타임스탬프를 전달한다. ServerMove RPC함수를 호출한다. 

 

3. 서버에서 실행되는 ServerMove에서는 movement 파라미터를 디코딩한 정보를 토대로 캐릭터에 이동을 적용한다.

이동 결과 위치와 응답 시간의 차이를 비교하여 차이가 충분히 큰 경우 서버는 ClientAdjustPosition RPC 함수를 호출하여 클라이언트상 액터의 위치를 서버 버전의 위치로 조정한다. bUpdatePosition 플래그를 true로 설정한다.

 

4. 다음 프레임의 TickComponent 함수에서 bUpdatePosition 플래그가 true라면 ClientUpdatePosition함수를 호출하는데, 

여기에서는 서버 버전의 위치로 조정된 이동의 시점 이후 입력된 이동들(Pending move list에 저장된)을 모두 리플레이한다. (클라이언트와 서버의 Latency 사이에 발생한 입력들에 대한 처리가 필요하기 때문에) 

bUpdatePosition 플래그는 다시 false로 바꿔준다.

 

5. 다른 클라이언트가 소유한 액터(Simulated Proxy)의 움직임 업데이트 대부분은 매 틱마다 호출되는 SimulateMovement 함수와 내부에서 호출되는 MoveSmooth에서 이루어진다. 서버 업데이트를 받았을 때 simulated proxy의 위치가 튀어보이는것을 방지하기 위해 SmoothClientPosition 함수를 사용하여 캐릭터 표현 위치에 스무딩 작업을 해 준다.

 

 

https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Networking/CharacterMovementComponent/

 

Character Movement Component

Detailed explanation of Character Movement Component

docs.unrealengine.com

'언리얼 5 > 정리' 카테고리의 다른 글

게임 플레이 아키텍처, 스마트 포인터, 태스크  (0) 2022.10.18
개발 구성, 엔진 아키텍처  (0) 2022.10.18
액터 종류  (0) 2022.10.18
레벨, 월드 세팅, 월드 파티션  (0) 2022.10.15
애셋과 레퍼런스  (0) 2022.10.14

+ Recent posts