I am new to C++ and UE4. I come from a Java background. So, please be gentle here. I am currently trying to build a game that allows the player to pick up items (I know... completely unique idea...). The items are being stored in a TArray of custom inventory item objects. Each inventory item object represents the item properties as well as the amount of the item currently in the inventory. So far, everything seems to be functioning as designed. When I click on a pickup Item in the game level, it puts an inventory item object in the inventory component. I have watched through breakpoints etc. and have seen that it is assigning the inventory items and counts properly. However, after about a minute, the inventory item object in the TArray suddenly mutates and contains all garbage data (default values or even random values). I am guessing that this is due to garbage collection or something. What I don't know is how to fix it. I have tried changing the way the inventory item is created and it doesn't seem to make any difference.
Here is the declarations for the pertinent info from the InventoryComponent.h:
private:
/* This is a pointer to the character that owns the inventory component */
class APilferCharacter* OwningCharacter;
/* These are the items that are currently in the inventory */
class TArray<class UInventoryItem*> Items;
class UInventoryItem* CreateInventoryItem(TSubclassOf<class UInventoryItem> InventoryItemClass);
public:
/*
Adds a given number of the specified item to the inventory
Returns the actual number of items added (May be less than the requested amount if there is not enough space)
*/
UFUNCTION(BlueprintCallable, Category = "Inventory")
uint8 AddItem(TSubclassOf<class UInventoryItem> InventoryItemClass, uint8 count = 1);
Here is the code for adding the inventory item to the UInventoryComponent:
UInventoryComponent::UInventoryComponent()
{
MaxArrows = 15;
MaxPotions = 3;
this->Items.SetNum(0);
}
UInventoryItem* UInventoryComponent::CreateInventoryItem(TSubclassOf<UInventoryItem> InventoryItemClass)
{
UInventoryItem* InventoryItem = NewObject<UInventoryItem>(this, InventoryItemClass);
InventoryItem->OwningInventory = this;
InventoryItem->World = GetWorld();
return InventoryItem;
}
uint8 UInventoryComponent::AddItem(TSubclassOf<UInventoryItem> InventoryItemClass, uint8 count)
{
uint8 actualAddedCount = 0;
if (count > 0) {
UInventoryItem* itemToAdd = CreateInventoryItem(InventoryItemClass);
UInventoryItem* existingItem = GetItemBySubType(itemToAdd->GetInventoryItemSubType());
uint8 MaxItemCount = GetMaxItemsByType(itemToAdd->GetInventoryItemType());
uint8 CurrentItemCount = 0;
if (existingItem) {
CurrentItemCount = existingItem->GetItemCount();
}
uint8 availableSpace = MaxItemCount - CurrentItemCount;
actualAddedCount = std::min(count, availableSpace);
itemToAdd->SetItemCount(actualAddedCount);
if (existingItem)
{
actualAddedCount = existingItem->Add(actualAddedCount);
}
else
{
Items.Add(itemToAdd);
}
if (actualAddedCount > 0) {
// Call the delegate to update the UI
if (OnInventoryUpdated.IsBound())
{
OnInventoryUpdated.Broadcast();
}
}
}
return actualAddedCount;
}
How do I make it so that the inventory items will last for the duration of the Component?
Thanks in advance
Ok! So, after scouring the interwebs for a solution I came across this webpage: https://www.programmersought.com/article/40121301538/
As I was reading through it, I came across a bit that talked about UPROPERTY() handling the GC for TArrays. I then realized that I had not added the UPROPERTY() to the TArray (I figured that it did not matter since it was a private property). So, I figured that I would add it in and see if it made a difference and VOILA! It appears to have worked!
So, by changing
/* These are the items that are currently in the inventory */
class TArray<class UInventoryItem*> Items;
to
/* These are the items that are currently in the inventory */
UPROPERTY()
class TArray<class UInventoryItem*> Items;
The array seems to hold the values properly and not turn them into random values after a minute or so.