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!
Here is the struct
USTRUCT()
struct FFCUnitOrderInfo
{
GENERATED_USTRUCT_BODY()
/*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;
//Constructor
FFCUnitOrderInfo()
{
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());
}
someunits.Empty();
someorders.Empty();
someunits.Add(tempunits[unitsearchindex]);
someorders.Add(temporder);
PlayerGiveOrdersToUnits(someunits, someorders);
The primary function
void AFCPlayerController::PlayerGiveOrdersToUnits(const TArray<AFCUnit*>& InUnits, const TArray<FFCUnitOrderInfo>& InOrders)
{
if (Role < ROLE_Authority)
{
ServerPlayerGiveOrdersToUnits(InUnits, InOrders);
}
else
{
int32 i = 0;
int32 j = 0;
for (i = 0; i < InUnits.Num(); i++)
{
if (InUnits[i])
{
for (j = 0; j < InOrders.Num(); j++)
{
InUnits[i]->CurrentOrders.Add(InOrders[j]);
}
}
}
}
}
The RPC
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