Replicated Variable is not being replicated

Ok, so, I’ve been fighting this one for a day or so now and I’ve got nothing.

I have an Actor Component for my Inventory, and inside of that I have 4 properties that are pointers to a weapon.

The Inventory spawns fine and replicates to clients, but the contents of that inventory do not. Everything I’ve seen so far in the documentation states that it should replicate, but I’m having no luck.

is the relevant part of my header. As you can see, all of the uproperties are marked Replicated.



 #pragma once
 
 #include "Object.h"
 #include "Core.h"
 #include "BaseEmpiresInventory.generated.h"
 
  UCLASS()
 class EMPIRES2_API UBaseEmpiresInventory : public UActorComponent
 {
     GENERATED_UCLASS_BODY()
 public:
 
     UPROPERTY(VisibleAnywhere, Category = General, Replicated, ReplicatedUsing=OnRep_Pistol)
     class ABaseEmpiresWeapon* Pistol;
     UPROPERTY(VisibleAnywhere, Category = General,  Replicated, ReplicatedUsing = OnRep_Primary)
     ABaseEmpiresWeapon* Primary;
     UPROPERTY(VisibleAnywhere, Category = General,  Replicated, ReplicatedUsing = OnRep_Tertiary)
     ABaseEmpiresWeapon* Tertiary;
     UPROPERTY(VisibleAnywhere, Category = General,  Replicated, ReplicatedUsing = OnRep_Special)
     ABaseEmpiresWeapon* Special;
 
     UFUNCTION()
     void OnRep_Pistol();
     UFUNCTION()
     void OnRep_Primary();
     UFUNCTION()
     void OnRep_Tertiary();
     UFUNCTION()
     void OnRep_Special();         
 
    ///More functions
     
 };
 

is the .cpp file


 void UBaseEmpiresInventory::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
 {
     Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
     DOREPLIFETIME(UBaseEmpiresInventory, Pistol);
     DOREPLIFETIME(UBaseEmpiresInventory, Primary);
     DOREPLIFETIME(UBaseEmpiresInventory, Tertiary);
     DOREPLIFETIME(UBaseEmpiresInventory, Special);
     
 }
 
 ///Snip
 
 void UBaseEmpiresInventory::OnRep_Pistol()
 {
     TRACE("Pistol Replicated: %u", Pistol);
 }
 
 void UBaseEmpiresInventory::OnRep_Primary()
 {
     TRACE("Primary Replicated: %u", Primary);
 }
 
///...


As you can see, The inventory items are set to be replicated.

I construct the character like this:


 AEmpires2Character::AEmpires2Character(const class FPostConstructInitializeProperties& PCIP)
     : Super(PCIP)
 {
     ///.... Snipped extra code that isn't relevant
 
     Inventory = PCIP.CreateDefaultSubobject<UBaseEmpiresInventory>(this, TEXT("Inventory"));
     Inventory->SetNetAddressable();
     Inventory->SetIsReplicated(true);
 
     this->bAlwaysRelevant = true;
 }

So, it should be replicating according to all of the documentation on the wiki and on the docs.

However, whenever I run my game, the client does not have the properties replicated to the client. All those pointers are NULL, and the OnRep functions aren’t being called.

Any ideas on what I’m doing wrong?

Can you explain it a bit futher are the void UBaseEmpiresInventory::OnRep_Pistol() beeing called at all?
When you set the value for e.g: Pistol is it done server side?

The derived actor component for your inventory set up for replication?
https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Replication/Components/index.html

Nice if you show us how you set your members and so on, so we may see where you potentualy went wrong.

Yeah, I’m setting the variables on the server. is where:


void AEmpires2Character::PossessedBy(AController * NewController)
{
	Super::PossessedBy(NewController);

	if (Role == ROLE_Authority && Controller)
	{
	

		AEmpiresPlayerState* playerState = GetEmpiresPlayerState();
		if (!playerState) return;

		//Add the primary and secondary weapons

		ABaseEmpiresWeapon* Pistol = GetWorld()->SpawnActor<ABaseEmpiresWeapon>(playerState->DefaultClass->Pistol);
		Pistol->SetOwner(this);
		Inventory->AddItem(EInfantryInventorySlots::Slot_Sidearm, Pistol);

		ABaseEmpiresWeapon* Rifle = GetWorld()->SpawnActor<ABaseEmpiresWeapon>(playerState->DefaultClass->Primary);
		Rifle->SetOwner(this);
		Inventory->AddItem(EInfantryInventorySlots::Slot_Primary, Rifle);



		SwitchToWeapon(EInfantryInventorySlots::Slot_Primary);
	}

}

I know the if statement is entirely redundant (as PossessedBy is only ever called on the server, I was copy+pasting this block of code around to see if that was the issue). AddItem is setting it to the correct slot. On the server (when Role is Authority), the inventory is being set correctly, and the weapon shows up. On clients, this is not the case.

As for the OnRep not being called… It’s just not being called. The log statement isn’t showing up in the log, when I set a breakpoint it is never triggered.

As for that article you linked, I followed it. Everything is set up according to that article.

Did you remember: #include “Net/UnrealNetwork.h”?

Yes. It would not compile if it didn’t

Aha. My weapons were not set to replicate. This is fixed now