UnrealEngineer
[ UnrealEngine5 ] 액터의 리플리케이션 본문
- 액터의 리플리케이션(Replication) 정의
리플리케이션 : 서버가 클라이언트에게 변경된 내용을 변수, 함수로 복제해주는 것
사용자의 환경이 각각 다 다르기 때문에 네트워크 통신(데이터 전송)을 최소화 하는 것이 중요하다.
네트워크 통신을 최소화하고 유효성 검사만을 통해 클라이언트 스스로 로딩하는 것이 효율적이다.
- 고정 액터 : 레벨을 구성하는 배경 액터
- 동적 액터 : 플레이어컨트롤러, 폰
동적 액터와 고정 액터를 구분하기 위해 언리얼엔진은 모든 액터에는 NetLoadOnClient라는 속성이 있다. (기본값 true)
이를 통해 네트워크와의 통신없이 클라이언트의 자체적인 로딩을 통해 효과적으로 구현할 수 있다.
서버의 컨텐츠 변경 사항을 모두 보내기 보다는
변경을 일으키는 속성 값의 변경치를 전달한다.
Replicates = true
하지만, Replicates = true로 설정하면 모든 액터의 속성값이 네트워크로 전달되기 때문에 비효율적이다.
그러므로 속성값의 변화에 따라서 원하는 동작을 스스로 수행할 수 있도록 데이터 기반으로 설계하는 것이 중요하다.
- 액터의 리플리케이션 방법
1. 액터의 리플리케이션 속성을 true로 지정
※ bReplicates = true;
2. 네트워크로 복제할 액터의 속성을 키워드로 지정
※ UPROPERTY에 Replicated 키워드 설정
3. GetLifetimeReplicatedProps 함수에 복제할 속성을 추가
< LifeTime은 액터 채널의 LifeTime을 의미한다. 즉, 활성화된 액터 채널로 전송할 복제될 속성을 의미함 >
※ #include "Net/UnrealNetwork.h"
※ DOLEPLIFETIME 매크로를 사용해 복제할 속성을 명시한다.
public:
// 서버에서 복제될 프로퍼티
UPROPERTY(Replicated)
float ServerRotationYaw;
public:
virtual void Tick(float DeltaTime) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
#include "Net/UnrealNetwork.h"
void ABCPortal::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 서버에서 실행
if(HasAuthority())
{
AddActorLocalRotation(FRotator(0.0f, RotationRate * DeltaTime, 0.0f));
// 서버의 회전값을 저장해준다.
ServerRotationYaw = RootComponent->GetComponentRotation().Yaw;
}
else
{
// 클라이언트인 경우
FRotator NewRotator = RootComponent->GetComponentRotation();
NewRotator.Yaw = ServerRotationYaw;
RootComponent->SetWorldRotation(NewRotator);
}
}
void ABCPortal::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ABCPortal, ServerRotationYaw);
}
매 틱마다 서버에서 프로퍼티의 변경이 일어날때마다 네트워크로 데이터 전송이 일어난다.
환경이 좋지 못한 클라이언트의 경우에는 서버와의 딜레이가 발생할 수 있고 많은 데이터의 전송은 원활한 환경구성의 저해 요소이다.
이러한 경우를 방지하기 위해서 콜백함수 구현을 통한 동기화 방법이 존재한다.
리플리케이션 콜백 함수 호출
1. 클라이언트에 속성이 복제될때 콜백 함수가 호출되도록 구현한다.
○ UPROPERTY의 Replicated 키워드를 ReplicatedUsing = OnRep_함수 형태의 키워드로 변경
○ ReplicatedUsing에 호출될 콜백 함수는 UFUNCTION 형태로 선언
2. 콜백 함수의 구현
○ OnRep_ 접두사를 붙여서 선언한다.
○ 콜백 함수는 서버가 아닌 '클라이언트'에서만 호출된다.
public:
ABCPortal();
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<class UStaticMeshComponent> StaticMeshComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<class UBoxComponent> BoxComponent;
// 서버에서 복제될 프로퍼티
UPROPERTY(ReplicatedUsing = OnRep_ServerRotationYaw)
float ServerRotationYaw;
UPROPERTY()
float RotationRate = 30.0f;
// 콜백함수 선언
UFUNCTION()
void OnRep_ServerRotationYaw();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
void ABCPortal::OnRep_ServerRotationYaw()
{
BC_LOG(LogBCNetwork, Log, TEXT("Yaw : %f"), ServerRotationYaw);
// 클라이언트인 경우
FRotator NewRotator = RootComponent->GetComponentRotation();
NewRotator.Yaw = ServerRotationYaw;
RootComponent->SetWorldRotation(NewRotator);
}
void ABCPortal::BeginPlay()
{
Super::BeginPlay();
}
void ABCPortal::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 서버에서 실행
if(HasAuthority())
{
AddActorLocalRotation(FRotator(0.0f, RotationRate * DeltaTime, 0.0f));
// 서버의 회전값을 저장해준다.
ServerRotationYaw = RootComponent->GetComponentRotation().Yaw;
}
}
void ABCPortal::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ABCPortal, ServerRotationYaw);
}
리플리케이션 함수는!
값이 변경될때만 호출해서 클라이언트에 복제해준다.
(서버에서 계속 호출되더라도 값의 변경이 없으면 복제는 일어나지 않는다.)
- 블루프린트와 C++ 네트워크
'언리얼엔진5' 카테고리의 다른 글
[ UnrealEngine5 ] 액터 리플리케이션 로우레벨 플로우 (0) | 2024.08.25 |
---|---|
[ UnrealEngine5 ] 액터 리플리케이션 빈도와 연관성(UnrealInsights) (0) | 2024.08.25 |
[ UnrealEngine5 ] 연결과 오너 (0) | 2024.08.21 |
[ UnrealEngine5 ] 게임모드와 로그인 (0) | 2024.08.19 |
[ UnrealEngine5 ] 캐릭터 애니메이션 (0) | 2024.08.19 |