Unreal Engine 멀티플레이어 게임 개발 5

1. Property Replication
- NetLoadOnClient == true
레벨에 고정적으로 배치되는 엑터에 설정하여 모든 클라이언트에 스스로 스폰하도록 함.

🚩 실습 : BP_Actor > Details > NetLoadOnClient 속성을 false/true로 바꿔가며 PIE 진행
- Replication Notify
👉 서버의 속성 값이 클라이언트에 복제될 때, 자동으로 특정 함수를 호출하도록 등록하는 기능.
매 틱마다 값을 폴링하는 것보다 훨씬 효율적
// 헤더
UPROPERTY(ReplicatedUsing = OnRep_Health)
float Health;
UFUNCTION()
void OnRep_Health();
// 소스
void AMyCharacter::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyCharacter, Health);
}
void AMyCharacter::OnRep_Health()
{
// 값이 바뀔 때만 여기가 호출됨
UpdateHealthBar();
}
| ReplicatedUsing= | 콜백 함수 이름을 지정 |
| OnRep_ 접두사 | 콜백 함수 이름에 반드시 붙여야 함 |
| UFUNCTION() | 콜백 함수에 반드시 붙여야 함 |
- OnRep_ 함수는 클라이언트에서만 호출된다. 서버에서는 호출되지 X
- 이전 값이 필요하다면 함수 파라미터로 받을 수 있다: void OnRep_Health(float OldHealth)
- GetLifetimeReplicatedProps에서 DOREPLIFETIME으로 복제 등록도 여전히 필요.
| C++ OnRep_ 함수 | Blueprint RepNotify 함수 |
| 클라이언트에서만 호출 | 서버와 클라이언트 모두에서 호출 |
| 명시적 호출 가능 | 명시적 호출 불가능 |
| 속성 값이 변경될 때만 호출 | 서버는 항시 호출되고, 클라이언트는 속성 값 변경될 때만 호출 |
2. NetUpdateFrequency
- 액터 레플리케이션 빈도의 최대치.
- 1초당 몇 번 레플리케이션을 시도할지 지정한 값.
- 기본값은 100
- 즉 이론적으로 서버는 1/100초 간격으로 레플리케이션을 시도
‼️ NetUpdateFrequency는 최대치일 뿐 이를 보장하진 않는다.
주요 액터의 NetUpdateFrequency 속성 기본값
| Actor | 100 |
| Pawn | 100 |
| PlayerController | 100 |
| GameState | 10 |
| PlayerState | 1 |
네트워크 부하 줄이는 방법
방법 1 — 매 틱 복제
- 서버 위치를 매 틱마다 클라이언트로 전송
- 구현 단순, 네트워크 부하 지속 발생
방법 2 — Dead Reckoning (예측 동기화)
- 서버는 초기 위치(Location) + 속도(Velocity) 1회만 복제
- 클라이언트가 P = P₀ + V * t 로 직접 계산
- 네트워크 부하 최소화
3. Relevancy

레벨에 있는 모든 엑터의 정보를 클라이언트에 전송하기엔 너무 크다!!
따라서 여러 기준을 토대로 서버에서 해당 클라이언트 커넥션과 연관성을 판단하여 액터를 리플리케이션 해준다.
- 엑터 클래스의 연관성 판단 기준
📌 Owner
- 해당 액터를 소유하고 있는 액터. 해당 액터와 Owner는 연관성이 있다고 판단.
- ex) 무기 액터를 소유하고 있는 캐릭터
📌 Instigator
- 해당 액터에게 영향을 끼친 폰. 해당 액터와 Instigator는 연관성이 있다고 판단.
- ex) 데미지를 가한 폰
📌 AlwaysRelevant
- 해당 액터가 모든 클라이언트에게 항상 연관성이 있게끔 설정할 때 사용.
- ex) 엄청나게 큰 보스 몬스터가 있고, 레벨 내의 모든 플레이어에게 레플리케이션 할 때.
📌 NetUseOwnerRelevancy
- 오너 액터의 연관성으로 해당 액터의 연관성을 대신할 때 사용.
- ex) 캐릭터가 소유하고 있는 무기 액터. 캐릭터가 안 보이는데 무기만 보일 리 없기 때문.
📌 OnlyRelevantToOwner
- 오너 액터에게만 연관성을 가짐. 즉, 다른 액터와는 연관성 없음.
- ex) 길라잡이 액터. 굳이 다른 플레이어가 내 길라잡이 액터들을 볼 필요는 없다.
📌 NetCullDistance
- 뷰어와의 거리에 따라 연관성 여부를 결정.
- ex) 아주 먼 곳에 위치한 나무의 나뭇잎 액터. 가까우면 레플리케이션하고, 멀면 안 하게끔

- 폰 클래스의 연관성 판단 기준
👉 플레이어 컨트롤러에 빙의된 폰이 움직이면서 어떤 액터가 레플리케이션될지 결정
📌 Viewer
- 클라이언트 커넥션이 소유하고 있는 플레이어 컨트롤러를 가리킴
📌 ViewTarget
- 플레이어 컨트롤러가 빙의한 폰.
- Viewer에 의해 빙의된 ViewTarget이 레벨을 돌아다니는 것.
- 즉, 어떤 액터가 Viewer&ViewTarget 액터와 연관성이 있느냐 없느냐

🚩 APlayerController , APawn , AActor 클래스의 IsNetRelevantFor() 함수

4. NetPriority
👉 한정된 대역폭에서 클라이언트 전송 우선 순위 결정
AActor::GetNetPriority() 에서 계산
NetCullDistance 같은 연관성 관련 속성들이 계산에 반영된다.
그리고 직전 패킷을 보낸 후 경과 시간과 가중치, 이전 NetPriority 값 등을 곱해서 계산한다.
포화 상태가 아니라면 계산된 NetPriority 값을 기준으로 정렬된 순서대로 레플리케이션한다.
포화 상태
👉 액터 관련 데이터가 너무 커서 대역폭을 넘어선 경우

5. NetDormancy
- 휴먼(NetDormancy)
👉 프로퍼티 레플리케이션이나 RPC가 동작하지 않는 상태
자주 수정 되지 않을 때 활용할 것. 자주 수정되는 엑터를 휴먼 상태로 두면 오버 헤드 발생
네트워크 휴먼 상태들
| DORM_Never | 절대 휴면되지 않습니다. |
| DORM_Awake | 휴면 상태가 아닙니다. 레플리케이션 대상. (다시 휴면 될 수도 있는 상태) |
| DORM_DormantPartial | [Deprecated] 일부 커넥션에 대해서만 휴면 상태. |
| DORM_Initial | 휴면 상태로 시작하고, 필요할 때 깨울 수 있는 상태. |
| DORM_DormantAll | 모든 커넥션에게 휴면 상태. |
- Conditional Property Replication(조건식 프로퍼티 리플리케이션)
레플리케이션에 등록된 프로퍼티를 조건식을 통해 조정 가능
DOREPLIFETIME_CONDITION()
언리얼 엔진의 프로퍼티 리플리케이션 | 언리얼 엔진 5.7 문서 | Epic Developer Community
액터 프로퍼티 리플리케이션 방법에 대한 상세 정보입니다.
dev.epicgames.com
'내배캠Unreal_TIL > UE' 카테고리의 다른 글
| [TIL] 2026-03-20 | UE bool 과 uint8 사용 및 차이 (0) | 2026.03.20 |
|---|---|
| [TIL] 2026-03-18 | UE 숫자 야구 게임 (0) | 2026.03.18 |
| [TIL] 2026-03-16 | 멀티플레이 디버그 로깅과 이벤트 함수 (0) | 2026.03.16 |
| [TIL] 2026-03-13 | 게임 플레이 프레임워크 (2) | 2026.03.13 |
| [TIL] 2026-03-12 | Property Replication (0) | 2026.03.12 |