Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

TSubclassOf inside a UStruct inside a TArray not replicating properly over RPC

I have a subclass of Character intended to be a unit in an RTS, it has a templated array of UStructs containing details for orders, in a queue. To add to this queue I have an RPC that takes an array of units and orders and adds them to the queue. This almost works perfect except clients can't seem to send over one of the variables in the struct, a TSubclassOf

On the listen server, the player can order a base building to build a satellite structure, avoiding having to call the RPC the order goes through correctly and I can see in the unit's properties that the order has the class set to a blueprint class I made.

On the client everything but this TSubclassOf replicate over and get added to the queue. The 'unitclass' of the order is set to just Character, the default. I have replicated over TSubclassOf's before no problem so this is puzzling. Here is a screenshot of the properties for my client and listen server's bases, they should both be trying to make 'testimprovement' but one is trying to build a character! wokringalt text

Here is the struct

 struct FFCUnitOrderInfo

 /*The display text for the command*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 FText CommandDisplayName;

 /*The command type*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 EFCCommandTypes CommandType;

 /*Train/Build/BuildPeripheral uses this to specify unit class to train/build*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 TSubclassOf<ACharacter> UnitClass;

 /*the index of the page to ChangePage to*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 int32 DestinationPage;

 /*target actor for commands like attack, guard, gather etc*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 AActor* TargetActor;

 /*target location for commands like move*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 FVector TargetLocation;

 /*if this command is an order from train rally*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 bool IsRallyOrder;

 /*If this command is an order from the hotgroup*/
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FFCUnitOrderInfo")
 bool IsHotgroupOrder;

         CommandDisplayName = FText::GetEmpty();
         CommandType = EFCCommandTypes::None;
         UnitClass = ACharacter::StaticClass();
         DestinationPage = 0;
         TargetActor = nullptr;
         TargetLocation = FVector(0.0, 0.0, 0.0);
         IsRallyOrder = false;
         IsHotgroupOrder = false;

Here is the snippet that calls the function (in my player controller class)

 temporder = FFCUnitOrderInfo();
 temporder.CommandType = EFCCommandTypes::BuildBasePeripheral;
 temporder.IsHotgroupOrder = false;
 temporder.IsRallyOrder = false;
 tempdefaulttemplateunit = (AFCUnit*)subselectionunittemplate->UnitCommands[i].Commands[Idx - 1].UnitClass.GetDefaultObject();

 if (tempdefaulttemplateunit)
 temporder.UnitClass = TSubclassOf<ACharacter>(tempdefaulttemplateunit->GetClass());
 PlayerGiveOrdersToUnits(someunits, someorders);

The primary function

 void AFCPlayerController::PlayerGiveOrdersToUnits(const TArray<AFCUnit*>& InUnits, const TArray<FFCUnitOrderInfo>& InOrders)
     if (Role < ROLE_Authority)
         ServerPlayerGiveOrdersToUnits(InUnits, InOrders);
         int32 i = 0;
         int32 j = 0;
         for (i = 0; i < InUnits.Num(); i++)
             if (InUnits[i])
                 for (j = 0; j < InOrders.Num(); j++)


 bool AFCPlayerController::ServerPlayerGiveOrdersToUnits_Validate(const TArray<AFCUnit*>& InUnits, const TArray<FFCUnitOrderInfo>& InOrders)
     return true;

 void AFCPlayerController::ServerPlayerGiveOrdersToUnits_Implementation(const TArray<AFCUnit*>& InUnits, const TArray<FFCUnitOrderInfo>& InOrders)
     PlayerGiveOrdersToUnits(InUnits, InOrders);

I'm going to try storing it as a UClass* instead but I'd really love to know why this one variable doesn't replicate

Product Version: UE 4.9
more ▼

asked Oct 26 '15 at 04:38 PM in C++ Programming

avatar image

Draco Houston
11 3 5 8

avatar image Draco Houston Oct 27 '15 at 12:08 PM

As I foreshadowed at the end of the question, I tried a more generic 'UClass' pointer instead of the subclass of template. This networks fine, but here's the thing: That doesn't answer my question.

Is this a known issue with the TSubclassOf class? If not, do you want me to try repro it in a blank project?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question