Subobject properties not replicating.

I don’t know if this is actually working or it just seems like it is, but if it is it’s probably because your UMove reference is a default object. You could get the same effect with


<Role>_DoMove(TSubclassOf<UMove> NewMove)
{
  PerformMove(NewMove.GetDefaultObject());
}

This will not work if you start changing values of moves dynamically, which is not the correct way to do this anyhow.

You cannot replicate UObjects like you believe you are doing. You are not creating a UObject and sending it over the network. You are sending a reference to an object over the network that both the server and client agree exists. If you want to actually send more, dynamic data to the server you need to use UStructs. Make like a struct FRepMove that contains relevant data. It could also contain TSubclassOf to point to the type of move. Look at how FPointDamageEvent works. Its an FDamageEvent which points to a TSubclassOf. It contains additional, event specific values.

So say you want to replicate a move and maybe the speed it was performed at and the damage that was done, you would do:



USTRUCT()
struct FRepMove
{
  GENERATED_BODY()

  UPROPERTY() // properties dont need to be marked for replicated in a struct
  float MoveSpeed;

  UPROPERTY()
  float DamageDone;

  // this would contain maybe the base damage before some multiplier, the animation, the fx, the audio, etc. all that which can be loaded before the move was even performed
  UPROPERTY()
  TSubclassOf<UMove> Move;
}

class MYCharacter
{
  ...
  UPROPERTY(ReplicatedUsing=OnRep_Move)
  FRepMove ReplicatedMove;
}

void MYCharacter::OnRep_Move()
{
 // Do something with ReplicatedMove 
}


The client would send inputs to the server (and in a more advanced approach, also simulate the move on its end in order to predict the server accepting its move ahead of time). The server would then do the move and fill out the FRepMove on the character and clients would receive the FRepMove in like OnRep_Move. They would then be able to do something like display the damage done on the HUD and get the default object of the Move to playback the animation at MoveSpeed or do whatever you want with it (advanced: if the original client had already predicted this move, then they should not perform it again, just confirm it was performed - see how SavedMoves work in CharacterMovementComponent).