UE5) UObject Replicate

UObject Replicate

기본적으로 Actor만 Replicate를 지원한다.

특수한 경우 UObject도 Replicate시킬 수 있다.

Replicate 시킬 UObject 클래스 내부에 다음 함수를 구현

  • MyObj.h
virtual bool IsSupportedForNetworking() const override;

virtual bool CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack) override;

virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override;
  • MyObj.cpp
bool UAbilityBase::IsSupportedForNetworking() const
{
	return true;
}


bool UAbilityBase::CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack)
{
	AActor* Owner = Cast<AActor>(GetOuter());
	if (!Owner) return false;
	UNetDriver* NetDriver = Owner->GetNetDriver();
	if (!NetDriver) return false;

	NetDriver->ProcessRemoteFunction(Owner, Function, Parms, OutParms, Stack, this);

	return true;
}

int32 UAbilityBase::GetFunctionCallspace(UFunction* Function, FFrame* Stack)
{
	AActor* Owner = Cast<AActor>(GetOuter());
	return (Owner ? Owner->GetFunctionCallspace(Function, Stack) : FunctionCallspace::Local);
}

Outer는 네트워크에 연관되어있는 액터여야 함(ex 플레이어 컨트롤러)

이 오브젝트를 리플리케이트하여 정보를 가지고 있어야 할 클래스 내부에 다음 함수를 구현해야 한다.

virtual bool ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags) override;
bool UAbilityComponent::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
	bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
	
	//배열인 경우 사용
	for (auto& item : MyArray)
	{
		WroteSomething |= Channel->ReplicateSubobject(item, *Bunch, *RepFlags);
	}

	//단순 변수인 경우 사용
	WroteSomething |= Channel->ReplicateSubobject(MyReplicatedObjectValue, *Bunch, *RepFlags);
	
	return WroteSomething;
}

Replicate된 UObject의 사본 생성 및 Replicate

기존처럼 DuplicateObject 함수로 복사하면, 서버에서만 존재하게 된다.

복사할 때, 플레그를 설정해주어야 정상적으로 복제되어 생성된다.

DuplicateObject 함수에는 플래그를 넘겨줄 수 있는 기능이 없다.

StaticDuplicateObject(ability,GetOwner(),NAME_None,RF_Public);

위 함수를 사용하면 된다.

UObject와 RPC

일반적으로 UObject내부에서 Replicate나 RPC 호출은 불가능하다.

반드시 액터를 통해서 이루어져야 한다.

다음과 같은 경우도 안된다

액터(서버) -> 오브젝트(멀티캐스트)

서버에 있는 액터가 특정 오브젝트 내부의 멀티캐스트 함수를 호출해도 전혀 의미가 없다.

예외적으로 위의 UObject리플리케이션과 같이 오브젝트가 리플리케이트 되도록 코드설정을 해 준 경우는 가능하다.