참고 링크

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/replicate-actor-properties-in-unreal-engine?application_version=5.3

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/replicated-subobjects-in-unreal-engine?application_version=5.3

 

Actor

Replicated

  • Actor 내에서 Replicate 할 Property에 UPROPERTY() 선언
  • UPROPERTY() 내에 'Replicated' Specifier를 입력
#pragma once 
 
#include "DerivedActor.generated.h"
 
UCLASS()
class ADerivedActor : public AActor
{
    GENERATED_BODY()
 
public:
    // Property to replicate
    UPROPERTY(Replicated)
    uint32 Health;
 
    // Derived Actor constructor
    ADerivedActor(const class FPostConstructInitializeProperties & PCIP);
 
    // Override Replicate Properties function
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};
  • 해당 Actor의 bReplicates 옵션을 활성화
    • 생성자나 BP 옵션에서 제어
  • GetLifetimeReplicatedProps() 함수를 override하여 DOREPLIFETIME 매크로를 선언
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"
 
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
    bReplicates = true;
}
 
void ADerivedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    // Call the Super
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
    // Add properties to replicated for the derived class
    DOREPLIFETIME(ADerivedActor, Health);
}
  • 위와 같은 방식으로 Object 또한 Replicate를 할 수 있다.
  • Network를 거쳐서 참조되는 Object는 반드시 Network 기능이 지원되어야 한다.
    • 이를 확인하려면 UObject::IsSupportedForNetworking() 함수를 이용한다.

Network Replicated Reference

  • Replicated Actor
  • Replicated Component
  • Stably-named 하지만 Replicated 하지 않은 Actor나 Component
  • Package로부터 Load 된 UObject(Actor, Component도 아닌)

Stably-named Object

  •  Server와 Client 양쪽에 같은 이름으로 존재하는 Object를 지칭한다.
    • Actor가 Gameplay 중 Spawn되지 않고 Package로부터 직접 Load 되면 Stably-named하다.
  • Actor Component는 다음 케이스일 경우 Stably-named 하다.
    • Pacakge로부터 직접 load 된 경우
    • 간단한 생성자 호출로 추가 된 경우
    • UActorComponent::SetNetAddressable로 마킹 된 경우
      • Component의 이름을 Server와 Client가 모두 명확하게 알고 있는 경우
      • AActor C++ 생성자에서 추가되는 Component들이 그 대표적인 예시이다.

ReplicatedUsing

  • "OnRep_"으로 시작하는 함수를 지정해 Replicate 될 때마다 특정 행동을 부여할 수 있는 Specifier
#pragma once 
 
#include "DerivedActor.generated.h"
 
UCLASS()
class ADerivedActor : public AActor
{
	GENERATED_BODY()
 
public:
 
	// Replicated Property using OnRep_Value
	UPROPERTY(ReplicatedUsing=OnRep_Value)
	int32 HealthValue1;
 
	// Replicated Property using OnRep_ConstRef
	UPROPERTY(ReplicatedUsing=OnRep_ConstRef)
	int32 HealthValue2;
 
	// Replicated Property using OnRep_NoParam
	UPROPERTY(ReplicatedUsing=OnRep_NoParam)
	int32 HealthValue3;
 
	// Signature to pass copy of the last value
	UFUNCTION()
	void OnRep_Value(int32 LastHealthValue);
 
	// Signature to pass const reference
	UFUNCTION()
	void OnRep_ConstRef(const int32& LastHealthValue);
 
	// Signature to pass no parameter
	UFUNCTION()
	void OnRep_NoParam();
 
	// Derived Actor constructor
	ADerivedActor(const class FPostConstructInitializeProperties & PCIP);
};
  • ReplicatedUsing에 연결 될 함수들은 UFUNCTION()으로 선언되어 있어야 한다.
  • 또한 경우에 따라서 Parameter를 받을 수도 있다.
    • Parameter에 전달되는 값은 Replicated Property가 변경되기 이전의 값이다.
    • 변경된 이후의 값은 Property가 직접 들고 있다.
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"
 
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
	bReplicates = true;
}
 
void ADerivedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	// Call the Super
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
	// Add properties to replicated for the derived class
	DOREPLIFETIME(ADerivedActor, HealthValue1);
	DOREPLIFETIME(ADerivedActor, HealthValue2);
	DOREPLIFETIME(ADerivedActor, HealthValue3);
}
 
void ADerivedActor::OnRep_Value(int32 LastHealthValue)
{
	UE_LOG(LogTemp, Log, TEXT("OnRep_Value with value. Last value: %d"), LastHealthValue)
	// Add custom OnRep logic
}
 
void ADerivedActor::OnRep_ConstRef(const int32& LastHealthValue)
{
	UE_LOG(LogTemp, Log, TEXT("OnRep_ConstRef with const ref. Last value: %d"), *LastHealthValue)
	// Add custom OnRep logic
}
 
void ADerivedActor::OnRep_NoParam()
{
	UE_LOG(LogTemp, Log, TEXT("OnRep_NoParam with no parameter."))
	// Add custom OnRep logic
}
  • RepNotify는 C++과 BP에서 조금 다르게 동작한다.
    • BP로 RepNotify가 선언되어 있다면, Replicated Property에 대해 Set 함수가 호출될 때 RepNotify도 호출된다.
    • 하지만 기본적으로 Replicated Property의 Reference를 갖는 Function, Macro에서는
      값이 변경되더라도 RepNotify가 호출되지 않는다.

NotReplicated

  • Replicated 되는 Actor나 Struct 내에서 특정 Property를 Replicate 되지 않도록 한다.
#pragma once 
 
#include "DerivedActor.generated.h"
 
USTRUCT()
struct FMyStruct
{
	GENERATED_BODY()
 
	UPROPERTY()
	int32 ReplicatedProperty;
 
	// Not Replicated even though encompassing struct is Replicated
	UPROPERTY(NotReplicated)
	int32 NotReplicatedProperty;
};
 
UCLASS()
class ADerivedActor : public AActor
{
	GENERATED_BODY()
 
public:
	UPROPERTY(Replicated)
	FMyStruct ReplicatedStruct;
 
	// Derived Actor constructor
	ADerivedActor(const class FPostConstructInitializeProperties & PCIP);
};
  • 5.4버전 엔진 코드 기준으로는 NotReplicated Property는 GetLifetimeReplicatedProps() 내에서 DISABLE_REPLICATED_PROPERTY 선언을 해주어야 한다.
  • 다만 이는 Warning이 발생할 뿐이고 Error가 발생하지는 않는다.
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"
 
ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
	bReplicates = true;
}
 
void ADerivedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
	DOREPLIFETIME(ADerivedActor, ReplicatedStruct);
}

Conditional Replication

  • Replicated Property는 한번 등록되면 Lifetime 동안 해제할 수 없다.
  • 기본적으로 Replicated Property는 값이 바뀔 때에 Replicate 된다.
    • 그 즉슨, 값이 바뀌지 않으면 Replicate 되지 않고 Bandwidth를 점유하지 않는다.
    • 때문에 Replicate 조건을 부여하여 불필요한 Replicate를 줄이면 이는 성능 향상으로 이어진다.

Replication Condition

  • GetLifetimeReplicatedProps() 함수에서 DOREPLIFETIME() 매크로 대신
    DOREPTIME_CONDITION() 매크로를 사용한다.
#define DOREPLIFETIME_CONDITION(c,v,cond) \
{ \
	static_assert(cond != COND_NetGroup, "COND_NetGroup cannot be used on replicated properties. Only when registering subobjects"); \
	FDoRepLifetimeParams LocalDoRepParams; \
	LocalDoRepParams.Condition = cond; \
	DOREPLIFETIME_WITH_PARAMS(c,v,LocalDoRepParams); \
}
  • 이는 Replicated 뿐 아니라 ReplicatedUsing Specifier도 적용된다.
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"
 
void ADerivedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	// Call the Super
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
	// Add property replication with a condition
	DOREPLIFETIME_CONDITION(ADerivedActor, Health, COND_OwnerOnly);
}

RepNotify Condition

  • Replication System은 Replicate 뿐 아니라 RepNotify 호출에 대해서도 조건을 부여할 수 있다.
    • 이를 위해서는 DOREPLIFETIME_CONDITION_NOTIFY가 필요하다.
/** Allows gamecode to specify RepNotify condition: REPNOTIFY_OnChanged (default) or REPNOTIFY_Always for when repnotify function is called  */
#define DOREPLIFETIME_CONDITION_NOTIFY(c,v,cond,rncond) \
{ \
	static_assert(cond != COND_NetGroup, "COND_NetGroup cannot be used on replicated properties. Only when registering subobjects"); \
	FDoRepLifetimeParams LocalDoRepParams; \
	LocalDoRepParams.Condition = cond; \
	LocalDoRepParams.RepNotifyCondition = rncond; \
	DOREPLIFETIME_WITH_PARAMS(c,v,LocalDoRepParams); \
}
  • 코드를 보면 알 수 있듯이,
    DOREPLIFETIME_CONDITION_NOTIFY에서는 RepNotify 조건 외에 Replicate 조건도 지정할 수 있다.
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"
 
void ADerivedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	// Call the Super
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
	// Add property replication with a condition
	/** 	Use this to always execute RepNotify
	*	Associated OnRep called on client every time property replicates
	*/
	DOREPLIFETIME_CONDITION_NOTIFY(ADerivedActor, Health, COND_OwnerOnly, REPNOTIFY_Always);
 
	/** 	Use this to only execute RepNotify when property changes
	*	Associated OnRep called on client only when property changes
	*/
	DOREPLIFETIME_CONDITION_NOTIFY(ADerivedActor, Health, COND_OwnerOnly, REPNOTIFY_OnChanged);
}

Custom Condition

  • 다음 작업을 통해 엔진에서 제공하는 조건 외의 조건으로 Replicate를 조절할 수 있다.
    • Replication Condition을 COND_Custom으로 지정
    • bool 타입 혹은 이를 반환하는 함수를 PreReplication에 등록
#pragma once 
 
#include "DerivedActor.generated.h"
 
UCLASS()
class ADerivedActor : public AActor
{
    GENERATED_BODY()
 
public:
    UPROPERTY(Replicated)
    int32 Health;
 
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
 
    // Derived Actor constructor
    ADerivedActor(const class FPostConstructInitializeProperties & PCIP);
 
    virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
 
    // Custom Replication Condition override function
    bool IsInvincible();
};
  • PreReplication에 Custom Condition을 지정할 때에는 DOREPLIFETIME_ACTIVE_OVERRIDE 매크로를 사용한다.
// Built on Compile time and Disable to work with Array
#define DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(c,v,active) \
{ \
	static_assert(ValidateReplicatedClassInheritance<c, ThisClass>(), #c "." #v " is not accessible from this class."); \
	UE::Net::Private::FNetPropertyConditionManager::SetPropertyActiveOverride(ChangedPropertyTracker, this, (int32)c::ENetFields_Private::v, active); \
}

// Built on Compile time and Enable to Work with Array
#define DOREPLIFETIME_ACTIVE_OVERRIDE_FAST_STATIC_ARRAY(c,v,active) \
{ \
	static_assert(ValidateReplicatedClassInheritance<c, ThisClass>(), #c "." #v " is not accessible from this class."); \
	for (int32 i = 0; i < (int32)c::EArrayDims_Private::v; ++i) \
	{ \
		UE::Net::Private::FNetPropertyConditionManager::SetPropertyActiveOverride(ChangedPropertyTracker, this, (int32)c::ENetFields_Private::v##_STATIC_ARRAY + i, active); \
	} \
}

// Built on Runtime and Enable to Work with Array
#define DOREPLIFETIME_ACTIVE_OVERRIDE(c,v,active) \
{ \
	static_assert(ValidateReplicatedClassInheritance<c, ThisClass>(), #c "." #v " is not accessible from this class."); \
	static FProperty* sp##v = GetReplicatedProperty(StaticClass(), c::StaticClass(),GET_MEMBER_NAME_CHECKED(c,v)); \
	for (int32 i = 0; i < sp##v->ArrayDim; i++) \
	{ \
		UE::Net::Private::FNetPropertyConditionManager::SetPropertyActiveOverride(ChangedPropertyTracker, this, sp##v->RepIndex + i, active); \
	} \
}
  • 이제 Health는 IsInvincible()이 false일 때에만 Replicate된다.
#include "DerivedActor.h"
#include "Net/UnrealNetwork.h"

ADerivedActor::ADerivedActor(const class FPostConstructInitializeProperties & PCIP) : Super(PCIP)
{
	bReplicates = true;
}

void ADerivedActor::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const 
{
	// Call the Super 
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	// Add properties to replicated for the derived class
    DOREPLIFETIME_CONDITION(ADerivedActor, Health, COND_Custom);
}

/* Function where the Custom condition is registered. */ 
void ADerivedActor::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
{
	// Call the Super
    Super::PreReplication(ChangedPropertyTracker);

	/* Use a custom property replication condition In this case, a function IsInvincible() If the actor is invincible, don't replicate Health */
    DOREPLIFETIME_ACTIVE_OVERRIDE(ADerivedActor, Health, !IsInvincible());
}

bool IsInvincible()
{
	bool bIsInvincible = false;

	// Custom logic to determine invincibility...
	return bIsInvincible;
}
  • Custom Condition은 매우 편리해 보이지만 2가지 큰 이유로 자주 사용하지 않는다.
    • 첫째, 작업 시간과 소모 리소스가 크다
    • 둘째, Connection 기준을 변경할 수 없다.

ELifetimeCondition

  • DOREPLIFETIME_CONDITION(_NOTIFY) 매크로의 3번째 parameter로 전달하는 값들.
/** Secondary condition to check before considering the replication of a lifetime property. */
UENUM(BlueprintType)
enum ELifetimeCondition : int
{
	COND_None = 0							UMETA(DisplayName = "None"),							// This property has no condition, and will send anytime it changes
	COND_InitialOnly = 1					UMETA(DisplayName = "Initial Only"),					// This property will only attempt to send on the initial bunch
	COND_OwnerOnly = 2						UMETA(DisplayName = "Owner Only"),						// This property will only send to the actor's owner
	COND_SkipOwner = 3						UMETA(DisplayName = "Skip Owner"),						// This property send to every connection EXCEPT the owner
	COND_SimulatedOnly = 4					UMETA(DisplayName = "Simulated Only"),					// This property will only send to simulated actors
	COND_AutonomousOnly = 5					UMETA(DisplayName = "Autonomous Only"),					// This property will only send to autonomous actors
	COND_SimulatedOrPhysics = 6				UMETA(DisplayName = "Simulated Or Physics"),			// This property will send to simulated OR bRepPhysics actors
	COND_InitialOrOwner = 7					UMETA(DisplayName = "Initial Or Owner"),				// This property will send on the initial packet, or to the actors owner
	COND_Custom = 8							UMETA(DisplayName = "Custom"),							// This property has no particular condition, but wants the ability to toggle on/off via SetCustomIsActiveOverride
	COND_ReplayOrOwner = 9					UMETA(DisplayName = "Replay Or Owner"),					// This property will only send to the replay connection, or to the actors owner
	COND_ReplayOnly = 10					UMETA(DisplayName = "Replay Only"),						// This property will only send to the replay connection
	COND_SimulatedOnlyNoReplay = 11			UMETA(DisplayName = "Simulated Only No Replay"),		// This property will send to actors only, but not to replay connections
	COND_SimulatedOrPhysicsNoReplay = 12	UMETA(DisplayName = "Simulated Or Physics No Replay"),	// This property will send to simulated Or bRepPhysics actors, but not to replay connections
	COND_SkipReplay = 13					UMETA(DisplayName = "Skip Replay"),						// This property will not send to the replay connection
	COND_Dynamic = 14						UMETA(Hidden),											// This property wants to override the condition at runtime. Defaults to always replicate until you override it to a new condition.
	COND_Never = 15							UMETA(Hidden),											// This property will never be replicated
	COND_NetGroup = 16						UMETA(Hidden),											// This subobject will replicate to connections that are part of the same group the subobject is registered to. Not usable on properties.
	COND_Max = 17							UMETA(Hidden)
};

ELifetimeRepnotifyCondition

  • DOREPLIFETIME_CONDITION_NOTIFY 매크로의 4번째 parameter로 전달되는 값들
enum ELifetimeRepNotifyCondition
{
	REPNOTIFY_OnChanged = 0,		// Only call the property's RepNotify function if it changes from the local value
	REPNOTIFY_Always = 1,		// Always Call the property's RepNotify function when it is received from the server
};

SubObject

ReplicateSubobjects

class AMyActor : public AActor
{
    UPROPERTY(Replicated)
    UMySubObjectClass* MySubObject;
}

class UMySubObjectClass : public UObject
{
    UPROPERTY(Replicated)
    int32 Counter = 0;
}

void AMyActor::CreateMyClass()
{
    MySubObject = NewObject<UMySubObjectClass>();
    MySubObject->Counter = 10;
}

void AMyActor::ReplicateSubobjects(...)
{
    Super::ReplicateSubobjects(...);
    Channel->ReplicateSubobject(MySubObject); // Becomes a subobject here
}
  • Channel에 Subobject를 등록하지 않는다면, Client에서 해당 Subobject는 항상 null일 것이다.
  • Subobject를 Replicate 하더라도 그 안의 Property를 Replicate하려면 Specifier 선언을 따로 해줘야 한다.

Registered Subobject

  • Subobject를 Owning Actor/ActorComponent List에 등록
    • List에 등록 된 Object들은 Actor Channel에 의해 자동으로 replicate 된다.
    • 등록하 때 ELifetimeCondition을 통해 Replicate condition을 부여할 수 있다.
  • 이 방식은 ReplicateSubObjects 함수 사용에 대한 업무 부담을 줄여줍니다.
AMyActor::AMyActor()
{
    bReplicateUsingRegisteredSubObjectList = true;
}

void AMyActor::CleanupSubobject()
{
    if (MySubobject)
    {
        RemoveReplicatedSubobject(MySubObject);
    }
}

void AMyActor::CreateMyClass()
{
    CleanupSubobject();

    MySubObject= NewObject<UMySubObjectClass>();
    MySubObject->Counter = 10;
    AddReplicatedSubObject(MySubObject);
}

void AMyActor::CreateMyDerivedClass()
{
    CleanupSubobject();

    MySubObject = NewObject<UMyDerivedSubObjectClass>();
    AddReplicatedSubObject(MySubObject);
}

void AMyActor::ReplicateSubobjects(...)
{
    //deprecated and not called anymore
}
  • AddReplicatedSubObject 함수는 ReadyForReplication이나 BeginPlay, 또는 Subobject를 생성할 때 호출한다.
  • 이 중 ReadyForReplication에서 함수 호출 시 주의할 점이 있따.
    • ActorComponent에서 ReadyForReplication 함수는 InitComponent와 BeginPlay 사이에 호출된다.
    • 즉슨, Component를 이 함수 안에서 등록하게 되면 BeginPlay에서는 RPC를 수행할 수 있다는 의미이다.
  • Subobject를 수정하거나 삭제 할 때에는 반드시 RemoveReplicateSubObject 함수를 호출해야 한다.
    • 해당 함수를 호출하지 않고 수정/삭제 시, Object의 Destruction 과정에서 한번 더 Destroy가 Mark된다.
    • 이는 GC가 동작할 때 Crash를 유발할 가능성이 있다.
  • 이 부분의 코드를 수정 할 때, net.SubObjects.CompareWithLegacy를 Console Command로 설정하면
    Runtime에서 Registered SubObjectList와 이전 함수를 비교할 수 있다.
    • 차이점이 감지되면 ensure가 발생한다.

Components

  • Replicated Component도 기본적으로 Subobject와 동일하다.
    • Component의 경우에는 AllowActorComponentToReplicate 함수를 override 한다.
    • 이 때 각 Component의 Replicate Condition은 내부 조건문에 맞춰 판정, 반환해야 한다.
  • 만약 BeginPlay가 호출 된 이후에 Component의 ReplicateCondition을 바꾸고 싶다면,
    SetReplicatedComponentNetCondition 함수를 이용한다.
  • Owning Component List는 Condition이 확인되기 전에 각 Connection에 Replicate 되어야 한다.
    • 예를 들어 Componenet가 SkipOwner인 경우,
      SubObject가 OwnerOnly이더라도 Owner에게 Replicate 되지 않는다.
ELifetimeCondition AMyWeaponClass::AllowActorComponentToReplicate(const UActorComponent* ComponentToReplicate) const
{
    // Do not replicate some components while the object is on the ground.
    if (!bIsInInventory)
    {
        if (IsA<UDamageComponent>(ComponentToReplicate))
        {
            return COND_Never;
        }
    }
    Super::AllowActorComponentToReplicate(ComponentToReplicate);
}

void AMyWeaponClass::OnPickup()
{
    // Now replicate the component to all
    SetReplicatedComponentNetCondition(UDamageComponent, COND_None);
    bIsInInventory = true;
}

Complex Replication Condition

  • NetConditionGroupManager와 COND_NetGroup을 이용해 Replicate Condition을 새로 만들 수 있다.
  • 이는 Subobject와 PlayerController가 여러 Group에 동시에 속해 있을 때,
    이 중 하나의 Group에만 속해 있어도 Replicate된다.
FName NetGroupAlpha(TEXT("NetGroup_Alpha"))
  • 원하는 Subobject를 위에서 추가한 NetGroupAlpha Group에 추가한다.
FNetConditionGroupManager::RegisterSubObjectInGroup(MyAlphaSubObject, NetGroupAlpha)
  • Subobject를 Replicate 할 Client의 PlayerController를 이용해 같은 Group에 추가한다.
PlayerControllerAlphaOwner->IncludeInNetConditionGroup(NetGroupAlpha)
  • 이제 PlayerControllerAlphaOwner의 Client는 Owner Actor가 해당 Client의 Connection에 Replicate 될 때마다
    등록된 MyAlphaSubobject를 Replicate 받는다.

Client Subobject List

  • Server가 Replicated Subobject List를 관리하는 것처럼, Client도 자체적으로 Subobject List를 관리해야 한다.
    • 이는 특히 Client에서 Replay를 녹화할 때 중요하다.
    • 이 경우, Client의 Actor는 Replay에 기록할 때 일시적으로 Local Authority Role로 전환된다.
    • 그렇기에 Replay에 기록된 Actor은 Local Role에 상관 없이
      Client에서 자체적으로 Subobject List를 유지해야 한다.
  • 만약 Subobject가 Replicated Property라면, RepNotify를 사용함으로 더 쉽게 관리할 수 있따.
    • Client는 RepNotify를 통해 SubObject가 변경되었음을 확인하여,
      이전 포인터를 제거하고 새로운 것을 추가할 수 있다.
  • Server의 Subobject List에서 Replicated Subobject를 제거하면
    해당 Object의 Replicated Property가 Client에 Replicate 되지는 않는다.
    • 하지만 SubObject의 포인터는 UObject가 스스로를 Grabage라고 마크 하기 전까지 Net-Referencable하다.
    • Server가 UObject가 Invalid하다 탐지하게 되면,
      다음 Reflection 업데이트에서 Client로 하여금 자체적으로 해당 Subobject를 지우도록 알린다.

'UE5 > Network' 카테고리의 다른 글

[Network] Replication Execution Order  (0) 2024.06.28
[Network] Remote Procedure Calls(RPCs)  (0) 2024.06.28
[Network] Network Property  (0) 2024.06.25
[Network] Network Driver  (0) 2024.06.18
[Network] DemoNetDriver 및 Streamer  (0) 2024.06.17

+ Recent posts