Here is a snippet of how I have this whole inventory thing set up:
There is a pickup class from which designers can derive and then fill with data. Its properties look something like this:
&stc=1Inventory data is a struct containing immutable data (like an item’s specification of some sort). Designer can create its own templated items (e.g. equipable items, containers, consumables etc.) and its just one actor to him. He does not need to know what happens behind the scenes.
These properties do not change at runtime. Then I have an item struct:
USTRUCT(BlueprintType)
struct FInventoryItem
{
GENERATED_USTRUCT_BODY()
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Immutable Data")
FGuid UUID;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Immutable Data")
FStringAssetReference AssetReference; // This is a reference to the pickup actor
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Immutable Data")
FInventoryItemData ItemData; // This is just for easier data management at runtime, we get everything we need from AssetReference if needed.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Runtime Data")
bool bIsEquipped;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Runtime Data", meta = (EditCondition = "!bIsEquiped"))
FGuid ParentUUID;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Runtime Data", meta = (ClampMin = "1")
int32 ItemQuantity;
FInventoryItem();
bool operator==(const FInventoryItem& Other) const
{
return UUID == Other.UUID;
}
bool operator!=(const FInventoryItem& Other) const
{
return UUID != Other.UUID;
}
FArchive& operator<<(FArchive& Ar, FInventoryItem& InventoryItem)
{
Ar << InventoryItem.UUID;
Ar << InventoryItem.bIsEquipped;
Ar << InventoryItem.ParentUUID;
Ar << InventoryItem.ItemQuantity;
return Ar;
}
};
I have a copy of inventory data so that it’s easier to manipulate its properties at runtime but I really only care about the runtime data which I serialize to the database.