Replication fails for variables that are declared within the blueprint of an actor's Subobject

^ Title was a bit of a mouthful! Let me explain a bit better…

So I have a C++ class derived from UObject, called UCommand. I also have a C++ class Derived from UActorComponent, called UCommandComponent - this component is added to my player character Actor.

A UCommandComponent has a replicated array of UCommand’s. So when a UCommand is created on the server and added to the array inside the UCommandComponent, this UCommand should be replicated down to the client and appear in the same array on the corresponding component on the client. I have all this working correctly by overloading the ReplicateSubobjects on my component, as well as implementing the IsSupportedForNetworking and GetLifetimeReplicatedProps in the various places it’s needed.

So now when I create a new UCommand on the server and add it to the UCommandComponent, it magically also appears on the client and is automatically added to the component’s array there - so far, so good!

Still with me? Ok…

So these UCommand objects also have some replicated UPROPERTY values - it is here is where my weird problem begins…

To demonstrate the issue, if I’ve added a test integer variable here to UCommand, as follows:

UFUNCTION()
void TestFunc();

UPROPERTY(ReplicatedUsing = TestFunc)
int TestInt;

Now, after I create my UCommand on the server (and it successfully replicates this down to the client), I try altering the value of TestInt on the server. Hey presto, a short time later, my client’s TestFunc() is triggered, and the value of TestInt on the client now matches the value I had set on the server. All working so far! … however…

The intention is to create Blueprints who’s parent class is UCommand, and it’s instances of these blueprint classes that are actually added to the UCommandComponent’s array of UCommands.

If I create a blueprint derived from UCommand, let’s call it DerivedCommand, I can see ‘TestInt’ listed as an inherited variable on the left hand side - great, that’s what I’d expect!. But now… if I add another integer variable ‘AnotherTestInt’ inside this blueprint, and set it’s parameters in the details panel to ‘RepUsing’, I would have imagined that what I’ve done here is essentially mimic the setup of my ‘TestInt’ in the C++ UCommand base class above, except this variable is called AnotherTestInt, and it’ll call a different ‘value changed’ delegate when it’s value is changed on the client (the OnRep_AnotherTestInt function is added in the blueprint for this)

If I create a DerivedCommand on the server and add it to my UCommandComponent’s array of commands, then a new DerivedCommand is successfully replicated down to my client. If I then change the value of TestInt on the server (the c++ defined replicated property), then my client’s TestFunc() successfully triggers with the value of TestInt correctly matching the value that was just set on the server - all working as expected. However - If I now change the value of AnotherTestInt on the server, my RepNotify function is immediately called on the server (this doesn’t happen for my c++ declared variable, however I’ve read online that a blueprint’s ‘RepUsing’ DOES trigger this when the value changes locally and accross the network, so i think this is to be expected?)… but the value of AnotherTestInt never ever replicates down to the client, nor does my client’s RepNotify function ever get hit.

I’ve tested this even more thoroughly by setting the value of TestInt and AnotherTestInt on the server to the current game running time every single frame, and then printing the value of both TestInt and AnotherTestInt on the client every frame, TestInt is seen to count up from 0 forever… while AnotherTestInt remains at zero throughout. TestInt’s TestFunc() gets called once per second (which is correct, the integer value of the game running time changes once every second) while OnRep_AnotherTestInt fails to be hit. At the same time, if I print out these same values on the server, both TestInt and AnotherTestInt count up forever (although OnRep_AnotherTestInt seems to trigger every single frame, even if the value hasn’t changed)

I hope I’ve explained that ok… Any ideas?

I’ve also just tried adding a new replicated custom event, which is set to NetMulticast, in the DerivedCommand blueprint. This event just prints a ‘hello world’ string. If i call this on the server, the ‘hello world’ string is only printed by the server - the replicated DerivedCommand on the client isn’t triggered.