Can an arbitrary struct be passed via an RPC?

My project has custom networking requirements, with a need to send data directly between server and clients. I’ve been able to send data to a client RPC using an FString as a parameter, but I cannot send a struct - the project will not compile if I try. Is sending a struct possible? And if so, are there any examples for how this is done?

If it helps, is the code I’m using that fails to compile:

    // the struct
    USTRUCT()
    struct FClientRpcData
    {
    	GENERATED_USTRUCT_BODY()
    
    	public:
    		uint8 _Data[256];
    		uint32 _Hash;
    };

   // inside my class declaration (a custom PlayerController)
   UFUNCTION( Client, Reliable )
   void ClientRpcFunction( const FClientRpcData& Data );

    // inside the class implementation
   void AMyPlayerController::ClientRpcFunction_Implementation( const FClientRpcData& Data )
   {
    ....
   }

I get this error when I try to compile:

error C2511: 'void AMyPlayerController::ClientRpcFunction_Implementation(const FClientRpcData &)' : overloaded member function not found in 'AMyPlayerController'

About the first question, you should mark your member variables _Data and _Hash with a UPROPERTY() definition. This would allow UHT to generate serialization, retrospection and replication code for this type.

According to the compilation problem and this: https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Replication/RPCs/index.html your code looks good.

Good call on the UPROPERTY() definitions. I’ve added them. I’m still getting the same compile error though. Perhaps sending structs of data is just not possible in UE4?

There are two things you can try if this is not working (can`t see any errors).

1 Did you forget to add Replicated to the Struct member in your controller?

2 Add validation to the method. like this.

 // inside my class declaration (a custom PlayerController)
UFUNCTION( Client, Reliable, WithValidation )
void ClientRpcFunction( const FClientRpcData& Data );

Just to mention it you then also have to add a second method to you cpp file.

bool AMyPlayerController::ClientRpcFunction_Validate(const FClientRpcData &)

Also is a example on a replicated struct.

/** Contains inventory array and integer "condition". */
USTRUCT(Blueprintable)
struct FInventoryContainerStruct
{
	GENERATED_USTRUCT_BODY()

public:
	// Array of items containing the players inventory/ loot.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Player Class, FInventoryContainerStruct")
		TArray<FItemInventoryStruct> InventoryArray;

	// Changed everytime array is edited, to make sure array get replicated to client.
	UPROPERTY()
		int32 Condition;

	/**
	 * Update the Inventory Container to guarantee replication to owner. 
	 * @param: Pass in a posetive or negative integer. */
	void UpdateArrayCondition(int32 ToAdd)
	{
		Condition += ToAdd;
	}
};

// INventory for this player managed on server and replicated to client.
UPROPERTY(ReplicatedUsing = OnRep_InventoryArray, EditAnywhere, BlueprintReadWrite, Category = "Player Class, Inventory")
	FInventoryContainerStruct InventoryContainer;

// Adds a item to the inventory if space.
UFUNCTION(BlueprintCallable, Category = "Player Class, Inventory")
	void AddItemToInventory(const FItemInventoryStruct ItemToAdd);

UFUNCTION(Server, Reliable, WithValidation)
	void SERVER_AddItemToInventory(const FItemInventoryStruct ItemToAdd);

Hope it helps

Hi,

Did you try to send the struct itself ?

void ClientRpcFunction( FClientRpcData Data );

Hmm, that works! I thought I had tried that actually. I don’t know why it wouldn’t have worked the first time. Maybe I had something else wrong. Anyway, thanks!

Thanks for the response. I only just got a chance to look at this now, and luckily for me, uced’s response below was exactly what I needed. I really appreciate your help though. Thanks again!