액터 리플리케이션(Actor Replication) 은 네트워크 드라이버(Network Driver) (넷 드라이버)가 어떤 액터를 어떤 연결에 어떤 순서로 리플리케이트해야 하는지 결정하는 세부적인 다단계 프로세스입니다. 이 페이지에서는 액터 리플리케이션 프로세스를 간략하게 살펴봅니다.
대부분의 액터 리플리케이션은 UNetDriver::ServerReplicateActors 함수 내에서 이루어집니다. 이 함수에서는 먼저 서버가 각 클라이언트와 연관성이 있다고 판단한 모든 액터를 수집한 다음, 연결된 각 클라이언트가 마지막으로 업데이트된 이후 변경된 모든 프로퍼티를 전송합니다. 그런 다음 UActorChannel::ReplicateActor 함수가 특정 채널에 대한 액터 리플리케이션의 세부 사항을 처리합니다.
중요 프로퍼티
액터 업데이트 방식, 호출되는 특정 프레임워크 콜백, 그리고 현재 서버 틱 중에 액터를 리플리케이트할지 결정하는 데 사용되는 프로퍼티에 대해 정의된 흐름이 있습니다. 몇 가지 중요 프로퍼티는 다음과 같습니다.
| 프로퍼티 | 설명 |
|---|---|
AActor::NetUpdateFrequency |
액터가 리플리케이트되는 빈도를 결정합니다. |
AActor::PreReplication |
리플리케이션이 발생하기 전에 호출됩니다. |
AActor::bOnlyRelevantToOwner |
이 액터가 자신의 오너에만 리플리케이트되는 경우 true입니다. |
AActor::IsRelevancyOwnerFor |
bOnlyRelevantToOwner가 true일 때 연관성을 결정합니다. |
AActor::IsNetRelevantFor |
bOnlyRelevantToOwner가 false일 때 연관성을 결정합니다. |
AActor::NetDormancy |
액터가 휴면 상태인지 깨어 있는지 결정합니다. |
액터 리플리케이션 흐름 개요
액터 리플리케이션 프로세스는 대략 다음과 같은 단계로 구성됩니다.
- 리플리케이트할 액터를 결정하고 휴면 상태와 업데이트 빈도, 소유 연결을 결정하기 위한 확인을 수행합니다.
- 이러한 확인을 통과한 액터를 리플리케이션 고려 대상 목록에 추가합니다.
- 각 연결을 루핑하고 현재 액터 및 연결을 기반으로 확인을 수행합니다. 이 단계가 끝나면 각 연결에 대한 리플리케이션 고려 대상 액터 목록이 남게 됩니다.
- 각 연결의 우선순위에 따라 액터를 정렬합니다.
- 액터가 이 연결과 연관성이 있는지 결정합니다.
- 액터를 현재 연결에 리플리케이트합니다.
다음 섹션에서는 위 액터 리플리케이션 흐름 개요의 각 단계를 더 자세하게 살펴봅니다.
액터를 리플리케이션 고려 대상 목록에 추가
이 단계에서는 모든 액터에 대한 초기 패스를 수행해 AActor::SetReplicates(true) 가 해당 액터에 대해 호출되었는지 확인하여 리플리케이트를 활성화할 액터를 결정합니다. 리플리케이트가 활성화되는 각 액터에 대해 NetDriver는 다음 확인을 수행합니다.
- 이 액터가 초기에 휴면 상태인지 결정합니다(
ENetDormancy::DORM_Initial).- 초기에 휴면 상태이면 이 액터는 건너뜁니다.
AActor::NetUpdateFrequency값을 확인하여 현재 액터에 업데이트가 필요한지 결정합니다.- 아니라면 이 액터는 건너뜁니다.
AActor::bOnlyRelevantToOwner가 true면 소유 연결의 뷰어에서AActor::IsRelevancyOwnerFor를 호출하여 이 액터의 소유 연결에 대한 연관성을 확인합니다.- 연관성이 있다면 연결의 소유 연관성 목록에 추가합니다.
- 이 경우, 이 액터는 단일 연결에만 전송합니다.
이러한 초기 확인을 통과한 모든 액터에 대해 AActor::PreReplication 이 호출됩니다. AActor::PreReplication 에서 특정 연결에 대해 프로퍼티를 리플리케이트할지 결정할 수 있습니다. DOREPLIFETIME_ACTIVE_OVERRIDE 매크로를 사용하여 액터가 리플리케이트되는 연결을 구체적으로 제어할 수 있습니다. 위의 모든 확인을 통과한 액터는 리플리케이션 고려 대상 목록에 추가합니다.
각 연결 루핑
다음으로 시스템은 각 연결을 루핑하면서 현재 연결에 대해 이전 단계에서 결정된 리플리케이션 고려 대상 목록에 있는 각 액터에 다음과 같은 확인 작업과 액션을 수행합니다.
AActor::NetDormancy를 호출하여 현재 액터가 휴면 상태인지 결정합니다.- 이 액터가 이 연결에 대해 휴면 상태이면 이 액터는 건너뜁니다.
- 아직 채널이 없으면 다음을 수행합니다.
- 현재 액터가 있는 레벨을 클라이언트에서 로드했는지 결정합니다.
- 레벨이 로드되지 않았다면 이 액터는 건너뜁니다.
- 연결에 대해
AActor::IsNetRelevantFor를 호출하여 현재 액터가 연관성이 있는지 결정합니다.- 연관성이 없다면, 이 액터는 건너뜁니다.
- 현재 액터가 있는 레벨을 클라이언트에서 로드했는지 결정합니다.
위의 연결 소유 연관성 목록에 액터를 추가합니다. 이 시점의 목록에는 이 연결에 대해 휴면 상태가 아닌 연관성이 있는 액터가 포함됩니다. 이 목록에 있는 액터를 우선순위(AActor::GetNetPriority)에 따라 내림차순으로 정렬합니다. 우선순위에 따라 액터를 정렬하는 것은 특히 많은 수의 액터가 고려되고 있어 연결이 포화될 가능성이 있을 때 우선순위가 높은 액터가 우선순위가 낮은 액터보다 먼저 리플리케이션 대상으로 고려되도록 하고자 할 때 중요합니다.
저장된 액터 목록 루핑
이 연결의 리플리케이션 고려 대상 목록에 있는 각 액터에 대해 다음 작업을 수행합니다.
- 해당 연결이 이 액터가 있는 레벨을 로드하지 않은 경우, 해당 채널(있는 경우)을 닫고 계속합니다.
- 1초마다
AActor::IsNetRelevantFor를 호출하여 액터가 연결에 연관성이 있는지 결정합니다.- 5초 동안 연관성이 없으면 그 채널은 닫습니다.
- 연관성이 있는데 열린 채널이 없으면 채널을 엽니다.
- 어떤 시점에서든 이 연결이 포화된 경우
- 나머지 액터에 대해 다음 작업을 수행합니다.
- 1초 미만 동안 연관성이 있는 경우, 다음 틱을 강제 업데이트합니다.
- 1초 이상 연관성이 있는 경우,
AActor::IsNetRelevantFor를 호출하여 다음 틱을 업데이트할지 결정합니다.
- 나머지 액터에 대해 다음 작업을 수행합니다.
위의 모든 단계를 통과한 액터는 UActorChannel::ReplicateActor 호출을 통해 연결에 리플리케이트됩니다.
다음과 같은 몇 가지 방법으로 호출당 리플리케이트되는 클라이언트 UNetDriver::ServerReplicateActors 수를 제어할 수 있습니다.
- 엔진 환경설정 및 명령줄 실행인자:
-limitclientticks명령줄 실행인자로 프로젝트를 실행합니다.[/Script/Engine.Engine]엔진 환경설정 카테고리에서NetClientTicksPerSecond값을 변경합니다.
- 명령줄 실행인자:
-limitclientticks -ini:Engine:[/Script/Engine.Engine]:NetClientTicksPerSecond=<VALUE>명령줄 실행인자로 프로젝트를 실행합니다. 여기서<VALUE>는 사용하려는 초당 클라이언트 틱 수입니다.
- 콘솔 변수:
net.MaxConnectionsToTickPerServerFrame콘솔 변수를 설정합니다.
자세한 내용은 UNetDriver::ServerReplicateActors_PrepConnections 를 참조하세요.
액터를 연결에 리플리케이트
UActorChannel::ReplicateActor 는 액터와 액터의 모든 컴포넌트를 연결에 리플리케이트하는 주요 메서드입니다. 그 흐름은 다음과 같습니다.
- 이 액터 채널이 열린 이후 이번이 첫 번째 업데이트인지 결정합니다.
- 첫 번째 업데이트라면 초기 위치와 회전 등, 필요한 특정 정보를 직렬화합니다.
- 이 연결이 이 액터를 소유하고 있는지 결정합니다.
- 소유하고 있지 않고 이 액터의 역할이
ENetRole::ROLE_AutonomousProxy라면ENetRole::ROLE_SimulatedProxy로 다운그레이드합니다.
- 소유하고 있지 않고 이 액터의 역할이
- 이 액터의 변경된 프로퍼티를 리플리케이트합니다.
- 각 컴포넌트의 변경된 프로퍼티를 리플리케이트합니다.
- 삭제된 모든 컴포넌트에 대해 특수 삭제 명령을 전송합니다.
액터 목록이 모두 소진되거나 채널이 포화되면, 다음 연결이 고려되고 모든 연결이 업데이트될 때까지 이 프로세스가 반복됩니다.
추가 정보
액터 리플리케이션에 대한 자세한 내용은 언리얼 엔진 소스 코드의 다음 헤더 파일을 참조하세요.
/Engine/Source/Runtime/Engine/Classes/Engine/NetDriver.hUNetDriver::ServerReplicateActors에 대한 정보
/Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.hAActor및 그 함수와 프로퍼티에 대한 정보
/Engine/Source/Runtime/Engine/Classes/Engine/ActorChannel.hUActorChannel및UActorChannel::ReplicateActor에 대한 정보
/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.hENetRole및ENetDormancy같은 타입에 대한 정보