Replication of an object's variables when stored as a PlayerState member

I want to know how i can store my replicated variables in a separate UCLASS object stored as a member of my custom PlayerState.

I’m encountering difficulties initiating replication for variables stored in the UCLASS object. When I implement GetLifetimeReplicatedProps in the PlayerState class and call MetaData->GetLifetimeReplicatedProps , passing in the FLifetimeProperty array, I encounter a failed assert during packaging due to a mismatch of replicated indices in the child object.

Code example:

class AMyPlayerState : public APlayerState
{
   virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
   {
      Super::GetLifetimeReplicatedProps(OutLifetimeProps);

      // ERROR HERE - REPINDEX out of order during packaging
      MetaData->GetLifetimeReplicatedProps(OutLifetimeProps);  
   }
   UPROPERTY(BlueprintReadWrite, EditAnywhere)
   FMetaData* MetaData;
}

UCLASS(BlueprintType)
class UMetaData
{
   // no virtual method to override - implement directly
   void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const 
   {
      DOREPLIFETIME_CONDITION(UMetaData, Field, COND_None);
   }
   UPROPERTY(BlueprintReadWrite, Editanywhere, ReplicatedUsing=OnRep_Field)
   FString Field;

   UFUNCTION()
   void OnRep_Field();
}

Thank you for your consideration.

It doesn’t work like that. You can only replicate properties within the current object.

Implementing replication on custom UObjects seems to be rather complicated and ever-changing, I’ve never done it myself so I can’t really recommend it.

I’d recommend using an ActorComponent instead, which has builtin replication just like actors.

class UMetaData : public UActorComponent
{
    GENERATED_BODY()

    UMetaData()
    {
        SetIsReplicatedByDefault(true);
    }

    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override
    {
        Super::GetLifetimeReplicatedProps(OutLifetimeProps);
        DOREPLIFETIME_CONDITION(ThisClass, Field, COND_None);
    }
}