So, recently I have been trying to implement an InventorySystem in UE using C++ and Blueprints. For this, I implemented an ItemInventoryComponent with a TArray containing InventoryItem objects. I use the corresponding replication system as shown in the code down below. My problem now is that in the InventoryItem object, the ReplicatedUsing function, On_RepQuantity(), is not getting called when the Quantity changes, and I don’t know why. For more context, the OnRep_Items() functions in the ItemInventoryComponent works as it is supposed to. Also, the value is being replicated to the client, but the On_RepQuantity() is just not being called. I don’t know if I did something wrong or if this is default behavior or a bug I have encountered.
InventoryItem.h
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
virtual bool IsSupportedForNetworking() const override;
UFUNCTION(BlueprintNativeEvent, Category = "Inventory")
void OnRep_Quantity();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory", Replicated, meta = (ExposeOnSpawn = true))
FName ItemID;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Inventory", ReplicatedUsing=OnRep_Quantity, meta = (ExposeOnSpawn = true))
int32 Quantity = 1;
UPROPERTY(BlueprintAssignable, Category = "Inventory")
FRefreshQuantity RefreshQuantity;
InventoryItem.cpp
void UInventoryItem::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UInventoryItem, ItemID, COND_OwnerOnly);
DOREPLIFETIME_CONDITION(UInventoryItem, Quantity, COND_OwnerOnly);
}
bool UInventoryItem::IsSupportedForNetworking() const
{
return true;
}
void UInventoryItem::OnRep_Quantity_Implementation()
{
if (RefreshQuantity.IsBound())
{
RefreshQuantity.Broadcast();
}
}
ItemInventoryComponent.h
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UFUNCTION(BlueprintNativeEvent, Category = "Inventory")
void OnRep_Items();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory", ReplicatedUsing=OnRep_Items)
TArray<class UInventoryItem*> InventoryItems;
ItemInventoryComponent.cpp
UItemInventoryComponent::UItemInventoryComponent()
{
PrimaryComponentTick.bCanEverTick = false;
bReplicateUsingRegisteredSubObjectList = true;
}
void UItemInventoryComponent::BeginPlay()
{
Super::BeginPlay();
for(UInventoryItem* item : InventoryItems)
{
AddReplicatedSubObject(item);
CurrentInventorySize++;
}
}
void UItemInventoryComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UItemInventoryComponent, InventoryItems, COND_OwnerOnly);
}
//Notify Inventory has changed
void UItemInventoryComponent::OnRep_Items_Implementation()
{
if (RefreshInventory.IsBound()) {
RefreshInventory.Broadcast();
}
}