액터 리플리케이션
- 특정 플레이어에 속한 액터의 정보를 네트웍 내 다른 플레이어에게 복제하는 작업
- 클라이언트 - 서버 모델에서는 대부분 서버에서 클라이언트로 전달함.
- 리플리케이션의 방법에는 크게 두 가지가 있음.
1. 프로퍼티 리플리케이션
2. RPC (Remote Procedure Call)
기본 액터의 로딩
- 클라이언트가 초기화 될 떄 모든 액터 정보를 서버로부터 받는 것은 비효율적
- 따라서 기본 배경에 관련된 액터는 맵을 통해 스스로 로딩하도록 설계되어 있음.
- 고정으로 제공하는 액터와 동적으로 생성하는 액터
고정으로 제공하는 액터의 예 : 레벨을 구성하는 배경 액터
동적으로 생성하는 액터의 예 : 플레이어 컨트롤러와 폰 - 고정 액터에 대해 NetLoadOnClient속성을 체크해야 함 (기본값)
리플리케이션 작업에서 가장 중요한 것은 데이터 전송량을 최소화 하는 것
NetLaodOnClient 레벨에 배치된 액터라면 모두 참으로 설정되어 있는데, 서버와 통신없이 클라이언트 초기화 시 자체적으로 로딩된다.
리플리케이션 프로퍼티의 지정
- 액터의 리플리케이션 속성을 참으로 지정함
bReplicates 속성을 true로 설정 - 네트웍으로 복제할 액터의 속성을 키워드로 지정.
UPROPERTY에 Replicated 키워드 설정 - GetLifeTimeReplicatedProps 함수에 네트웍으로 복제할 속성을 추가.
#include "Net/UnrealNetwork.h" 헤더 파일 지정
DOREPLIFETIME 매크로를 사용해 복제할 속성을 명시
Lifetime 은 액터 채널의 Lifetime 을 의미함.
즉 활성화된 액터 채널로 전송할 복제될 속성을 의미함.
++)
프로퍼티 리플리케이션이란
네트워크 데이터를 최소화하기 위해선 변경시키는데 사용되는 데이터인 속성 값만 정리해서 보내는 방법 (state )
리슨 서버 모델에서는
클라이언트와 서버코드 분리해야한다.
데디케이티드 서버는 클라이언트 로직을 고려 안하기 때문에 서버 로직만 있으면 된다. (훨씬 편리)
매 틱마다 서버로부터 받은 속성을 업데이트 시켜 주면 매 프레임마다 실행되는 틱의 코드가 방대해지고 상대방의 네트워크 전송 주기가 틱보다 느리면 틱이 쌓여서 비효율적으로 동작할 수 있다.(와다다다 업데이트 됄 수 있다.)
따라서 더 효율적으로 프로퍼티 리플리케이션을 구성할 방법이 필요하다.
-> 리플리케이션 콜백 함수 호출
리플리케이션 콜백 함수 호출
- 클라이언트에 속성이 복제될 때 콜백 함수가 호출되도록 구현
UPROPERTY의 Replicated 키워드를 ReplicatedUsing 키워드로 변경
ReplicatedUsing에 호출할 콜백 함수를 지정.
호출될 콜백 함수는 UFUNCTION으로 선언해야 함. - 콜백 함수의 구현
일반적으로 OnRep_의 접두사를 가지는 이름 규칙을 가짐.
콜백 함수는 서버가 아닌 클라이언트에서만 호출됨.
필요한 타이밍에만 해당 로직을 처리할 수 있어 효율적인 구현이 가능하다.
액터 리플리케이션 -> 액터 채널 사용
액터채널이 열린다음에 리플리케이션이 진행된다.
소스 코드
// Called every frame
void AABFountain::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (HasAuthority())
{
AddActorLocalRotation(FRotator(0.0f, RotationRate * DeltaTime, 0.0f));
ServerRotationYaw = RootComponent->GetComponentRotation().Yaw;
}
else
{
}
}
void AABFountain::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AABFountain, ServerRotationYaw);
}
void AABFountain::OnRep_ServerRotationYaw()
{
AB_LOG(LogABNetwork, Log, TEXT("Yaw : %f"), ServerRotationYaw);
FRotator NewRotator = RootComponent->GetComponentRotation();
NewRotator.Yaw = ServerRotationYaw;
RootComponent->SetWorldRotation(NewRotator);
}
'언리얼엔진5 > [Part3] 이득우의 언리얼 프로그래밍' 카테고리의 다른 글
[이득우의 언리얼 프로그래밍 Part3 필기] 7. 액터 리플리케이션 로우레벨 플로우 (0) | 2024.05.06 |
---|---|
[이득우의 언리얼 프로그래밍 Part3 필기] 6. 액터 리플리케이션 빈도와 연관성 (0) | 2024.04.30 |
[이득우의 언리얼 프로그래밍 Part3 필기] 4. 액터의 역할과 커넥션 핸드셰이킹 (0) | 2024.04.27 |
[이득우의 언리얼 프로그래밍 Part3 필기] 3. 커넥션과 오너십 (0) | 2024.04.25 |
[이득우의 언리얼 프로그래밍 Part3 필기] 2. 게임 모드와 로그인 (0) | 2024.04.24 |