득이공간

[네트웍 멀티플레이 프레임웍의 이해] 2장. 액터 리플리케이션 본문

GP/UE5

[네트웍 멀티플레이 프레임웍의 이해] 2장. 액터 리플리케이션

쟁득 2024. 5. 17. 16:02
해당 게시물은 이득우 교수님의 '네트웍 멀티플레이 프레임웍의 이해' 강의를 수강하며
학습한 내용을 개인적으로 정리한 글입니다.

📌 목차 - 2장. 액터 리플리케이션

2-1. 액터 리플리케이션 기초

2-2. 액터 리플리케이션 빈도와 연관성

2-3. 액터 리플리케이션 로우레벨 플로우


📌 2-1. 액터 리플리케이션 기초

1. 액터 리플리케이션의 개요에 대한 학습
2. C++을 활용한 프로퍼티 리플리케이션의 구현
3. C++와 블루프린트간의 프로퍼티 리플리케이션 방식의 차이 비교

 

  • 이번 강의에서 학습할 내용
    • 액터 리플리케이션
    • 프로퍼티 리플리케이션
  • 액터 리플리케이션
    • 특정 플레이어에 속한 액터의 정보를 네트웍 내 다른 플레이어에게 복제하는 작업
    • 클라이언트-서버 모델에서는 대부분 서버에서 클라이언트로 전달한다.
    • 리플리케이션의 방법에는 크게 두 가지가 있다.
      • 프로퍼티 리플리케이션
      • RPC(Remote Procedure Call)
  • 기본 액터의 로딩
    • 클라이언트가 초기화 될 때 모든 액터 정보를 서버로부터 받는 것은 비효율적
    • 따라서 기본 배경에 관련된 액터는 맵을 통해 스스로 로딩하도록 설계되어 있다.
    • 고정으로 제공하는 액터와 동적으로 생성하는 액터
      • 고정으로 제공하는 액터의 예: 레벨을 구성하는 배경 액터
      • 동적으로 생성하는 액터의 예: 플레이어 컨트롤러와 폰
    • 고정 액터에 대해 NetLoadOnClient 속성을 체크해야 한다. (기본값)
  • 액터의 리플리케이션 설정
    • 고정으로 보여지는 액터 중, 게임 중 변경 사항이 발생하는 액터는 그 값을 전달해야 한다.
    • 네트웍 데이터를 최소화하기 위해 변경 사항을 보내기보다, 변경을 유발한 속성 값을 전달한다.
    • 이를 위해 액터의 Replicates 옵션을 체크해야 한다.
  • 리플리케이션 프로퍼티(속성)의 지정
    1. 액터의 리플리케이션 속성을 참으로 지정한다.
      • bReplicates 속성을 true로 설정
    2. 네트웍으로 복제할 액터의 속성을 키워드로 지정한다.
      • UPROPERTY에 Replicated 키워드 설정
    3. GetLifetimeReplicatedProps 함수에 네트웍으로 복제할 속성을 추가한다.
      • #include “Net/UnrealNetwork.h” 헤더 파일 지정
      • DOREPLIFETIME 매크로를 사용해 복제할 속성을 명시
    • Lifetime은 액터 채널의 Lifetime을 의미한다.
    • 즉, 활성화된 액터 채널로 전송할 복제될 속성을 의미한다.
  • 리플리케이션 콜백 함수 호출
    1. 클라이언트에 속성이 복제될 때 콜백 함수가 호출되도록 구현
      • UPROPERTY의 Replicated 키워드를 ReplicatedUsing 키워드로 변경
      • ReplicatedUsing에 호출할 콜백 함수를 지정
      • 호출될 콜백 함수는 UFUNCTION으로 선언해야 함
    2. 콜백 함수의 구현
      • 일반적으로 OnRep_의 접두사를 가지는 이름 규칙을 가짐
      • 콜백 함수는 서버가 아닌 클라이언트에서만 호출됨
    • 필요한 타이밍에만 해당 로직을 처리할 수 있어서 효율적인 구현이 가능하다.
  • C++ OnRep vs 블루프린트 RepNotify

📌 2-2. 액터 리플리케이션 빈도와 연관성

1. 언리얼 인사이트 도구의 사용 방법의 학습
2. 액터 리플리케이션 빈도 속성 조절에 따른 변화 확인
3. 액터 리플리케이션 연관성 설정에 따른 변화 확인

 

  • 이번 강의에서 학습할 내용
    • 액터 리플리케이션: 연관성, 빈도
  • 언리얼 인사이트(Unreal Insights)
    • 언리얼 프로그램의 다양한 퍼포먼스를 체크할 수 있는 강력한 프로파일링 도구
    • 언리얼 엔진에 포함되어 있음
    • 프로그램 프로파일링 뿐만 아니라 네트웍 상태도 확인할 수 있음 (Network Insights)
  • 언리얼 인사이트 구동을 위한 환경 설정
    • 언리얼 엔진의 설치 폴더 확인
    • 인사이트 프로그램의 숏컷 생성
    • 언리얼 에디터 실행 파일의 PATH 설정
    • 언리얼 에디터를 구동하기 위한 배치파일 제작
    • NetworkInsightsEditor.bat
    • UnrealEditor.exe %cd%\ArenaBattle.uproject -NetTrace=1 -Trace=Net
  • 액터 리플리케이션 빈도(Frequency)
    • 클라이언트와 서버간에 진행되는 통신 빈도
    • NetUpdateFrequency: 리플리케이션 빈도의 최대치 설정
      • 1초당 몇 번 리플리케이션을 시도할지 지정한 값
      • 기본 값은 100. 즉 이론적으로 서버는 1/100초 간격으로 리플리케이션을 시도함
    • 네트웍 빈도는 최대치일 뿐 이를 보장하진 않는다.
      • 서버의 Tick Rate에 따라 리플리케이션이 발생하지만, 서버의 성능에 따라 달라진다.
      • 서버의 성능이 네트웍 빈도보다 낮은 경우, 서버의 성능으로 복제된다.
      • 일반적으로 그래픽 기능이 없는 데디케이티드 서버가 더 좋은 성능을 발휘한다.
  • 주요 액터에 설정된 빈도 값
    • NetUpdateFrequency 속성
    • Actor: 100.0
    • Pawn: 100.0
    • PlayerController: 100.0
    • GameState: 10.0
    • PlayerState: 1.0
  • 네트웍 데이터 줄이기
    • 규칙적으로 움직이는 액터의 네트웍 통신 데이터를 줄이는 예제
    • NetUpdateFrequency 속성 값을 1로 설정
    • 데이터 공백을 클라이언트에서 부드러운 움직임으로 보완하기
      • 이전 복제된 데이터에 기반해 현재 틱에서의 회전 값을 예측
      • 클라이언트에서 예측된 값을 보간해 회전
  • 적응형 네트워크 업데이트 (Adaptive Network Update)
    • 유의미한 업데이트가 없으면 빈도를 줄여서 부하를 줄이는 기법
    • MinNetUpdateFrequency
      • 리플리케이션 빈도의 최소치 설정을 사용함
    • 최소 값과 최대 값 사이에서 현재 액터에 맞는 최적의 전송 타이밍을 설정함
    • 이를 사용하기 위해서는 설정에서 직접 활성화시켜줘야 함
    • DefaultEngine.ini
      • [SystemSettings] net.UseAdaptiveNetUpdateFrequency=1
  • 연관성(Relevancy)이란?
    • 서버의 관점에서 현재 액터가 클라이언트의 커넥션에 관련된 액터인지 확인하는 작업
    • 대형 레벨에 존재하는 모든 액터 정보를 클라이언트에게 보내는 것은 불필요함
    • 클라이언트와 연관있는 액터만 체계적으로 모아 통신 데이터를 최소화하는 방법
  • 연관성에 관련된 다양한 속성
    • 연관성 판별을 위한 특별한 액터의 정의
      • 뷰어(Viewer): 클라이언트의 커넥션을 담당하는 플레이어 컨트롤러를 가리킴
      • 뷰 타깃(View Target): 플레이어 컨트롤러가 빙의한 폰
      • 가해자(Instigator): 나에게 대미지를 가한 액터
    • 오너(Owner)의 정의
      • 액터를 소유하는 액터. 최상단의 소유 액터를 의미
  • 연관성의 점검
    • 서버에서는 틱마다 모든 커넥션과 액터에 대해 연관성을 점검함
    • 클라이언트의 뷰어와 관련있고 뷰어와의 일정 거리 내에 있는 액터를 파악
    • 해당 액터 묶음의 정보를 클라이언트에게 전송
  • 액터 속성에 따른 연관성 판정을 위한 속성
    • AlwaysRelevant
      • 항상 커넥션에 대해 연관성을 가짐
    • NetUseOwnerRelevancy
      • 자신의 연관성은 오너의 연관성으로 판정함
    • OnlyReleventToOwner
      • 오너에 대해서만 연관성을 가짐
    • Net Cull Distance
      • 뷰어와의 거리에 따라 연관성 여부를 결정
    • 액터, 폰, 플레이어 컨트롤러의 IsRelevantFor 코드 살펴보기

📌 2-3. 액터 리플리케이션 로우레벨 플로우

1. 액터에 설정된 우선권을 활용해 네트웍 포화 상태를 대처하는 방법의 이해
2. 액터 휴면 상태와 조건부 프로퍼티 설정에 대한 이해
3. 서버 로우레벨에서 진행되는 액터 리플리케이션 로직의 흐름 이해

 

  • 이번 강의에서 학습할 내용
    • 액터 리플리케이션: 우선권
  • 우선권(Priority)이란?
    • 클라이언트에 보내는 대역폭(NetBandwidth)은 한정되어 있음
    • 클라이언트에 보낼 액터 중, 우선권이 높은 액터의 데이터를 우선 전달하도록 설계되어 있음
    • 액터에 설정된 NetPriority 우선권 값을 활용해 전송 순서를 결정함
    • NetPriority 속성
      • Actor: 1.0
      • Pawn: 3.0
      • PlayerController: 3.0
  • 네트웍 트래픽 포화(Saturation)
  • 우선권 설정 로직
    • 마지막으로 패킷을 보낸 후의 경과 시간과 최초 우선권 값을 곱해 최종 우선권 값을 생성
    • 최종 우선권 값을 사용해 클라이언트에 보낼 액터 목록을 정렬함
    • 네트웍이 포화(Saturation)될 때까지 정렬된 순서대로 리플리케이션을 수행
    • 네트웍이 포화되면 해당 액터는 다음 서버 틱으로 넘김
    • 액터의 우선권을 계산하는 GetNetPriority 함수 로직액터의 상태 가중치 배수
      액터의 상태 가중치 배수
      현재 뷰타깃인 경우 4배
      잘 보이는 경우 2배
      잘 안보이는 경우 상황에 따라 0.2 또는 0.4
      플레이어 컨트롤러가 뷰어인 경우 4배
  • 액터의 휴면(Dormancy)이란?
    • 액터의 전송을 최소화 하기 위해 연관성과 더불어 제공하는 속성
    • 액터가 휴면 상태라면 연관성이 있더라도 액터 리플리케이션(RPC)을 수행하지 않음
    • 언리얼 엔진에서 지정한 휴면 상태
      • DORM_Never: 액터는 휴면이 없음
      • DORM_Awake: 액터는 깨어나 있음
      • DORM_DormantAll: 액터는 언제나 휴면 상태. 필요시에 깨울 수 있음
      • DORM_DormantPartial: 특정 조건을 만족할 경우에만 리플리케이션을 수행
      • DORM_Initial: 액터를 휴면 상태로 시작하고 필요한 때 깨우도록 설정할 수 있음
      • 속성 리플리케이션 사용시에는 DORM_Initial만 고려하는 것이 좋음
  • 조건식 프로퍼티 리플리케이션
    • 조건을 통해 트래픽 양의 최적화 가능
  • 액터 리플리케이션 흐름 (서버에서 매 Tick 마다 동작)
    1. 서버에서 클라이언트로 NetworkObjects 전송 (FNetworkObjectInfo: NextUpdateTime, bPendingNetUpdate)
    2. ConsiderList: NextUpdateTime 경과, DORM_Initial 휴면 상태 아님, PreReplication 호출
    3. 각 커넥션의 PriorityList에서 Relevancy 점검, 우선권 계산