Download

Replicate Array in ActorComponent

Hello,

I am struggling to understand why I am unable to replicate TArray of custom UStructs in my component derived from AActorComponent.

My custom UStruct looks like this:

USTRUCT(BlueprintType)
struct SURVIVALFPS_API FInventoryItem
{
GENERATED_BODY()

public:
FInventoryItem();

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UItemDataAsset* ItemRef = nullptr;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
int Count = 0;
};

And array is declared as following:

UPROPERTY(VisibleAnywhere, ReplicatedUsing = OnRepItems)
TArray<FInventoryItem> Items;

When I modify the array at some specific index, it does not trigger replication, the only thing that triggers replication is resizing the array. If I change the type inside TArray to int, I observe the same behaviour. I checked in editor that the array is correctly modified on the server.

However, I am able to replicate single FInventoryItem just fine. The component is marked for replication, ReplicatedUsing function is marked as UFUNCTION, I have DOREPLIFETIME set up correctly; the replication works just fine for non-array types.

The weird thing is that I can replicate the same TArray in my actor class, but not on the component.

Any help is greatly appreciated.

I’m not sure if you can “auto replicate” arrays like this. Though I must ask, why would you replicate inventory items anyways? They are only relevant to the local player (in most cases at least). So instead of replicating the whole array, you can track if an item is added and removed, and sync that with the clients. Anyways, as a workaround, you could make a function that simply sends the item array to client.

// Replicate an item array to the client.
UFUNCTION(Client, Reliable)
virtual void ClientReplicateItems(const TArray<FInventoryItem>& Items); 

Thank you for your response, currently I do use Client/Multicast RPCs for inventory, I was trying to rework it for a few reasons. I need to have inventories that are shared for multiple players, e.g. chests where players can put items, in which case I need to use Multicasts to share contents of such inventories. Similarly, I want to have equipment inventory, i.e. items which player has currently equipped, and I want to share that across the network so that other clients can update their local actors.

I don’t like using RPCs for that since they are not guaranteed to arrive in the order I send them, so inventories can get desynced at times. Also, for shared inventories, when a new client joins the game, I have to manually call RPCs to sync all existing inventories that should be shared.

Using replicated array seems like a better solution to me, and arrays do auto replicate correctly if I try to replicate them in player actor instead of inventory.

Also, according to some older references this should be possible:

https://michaeljcole.github.io/wiki.unrealengine.com/Replication/

Though they don’t specifically mention replicating arrays in ActorComponent, only in Actors.

Do you have both the actor component and its owner set to replicate?

Yes I do, and for all non-array types replication works.

I finally found the bug in my code that caused this, I have overridden InitializeComponent method in my inventory component but never called Super::InitializeComponent, which apparently caused that the array was not being synced.