Update Jul 24, 2014: I think I’ve figured out what’s causing the problem. But I don’t have a solution yet.
I was assuming my ‘add to inventory’ function was adding a copy of the item to the inventory array. However, what actually happened was that my function added a reference to the item to my inventory array. And at the end of the function, the item (in the world) is deleted. Every 60 seconds, Unreal’s garbage collector finishes removing all references to the destroyed actor, which is what caused my inventory item references to disappear.
There’s a bug in my game where my player inventory array seemingly empties itself at random. After testing many sequences of action in my game (picking up items, dropping items, organizing my inventory), I could not pinpoint the action or the action sequence that caused my inventory to clear itself. It seemed like no matter what I did, my inventory array wiped itself clean for no reason.
I decided to pick up an item and then do nothing at all, just to see what happens. My inventory still cleared itself. This was interesting.
I finally discovered it was time-related by tracking it with a stopwatch on my phone:
Time = 0: I start the game
Time = 8s: I add an item to my inventory
Time = 60s: My inventory array is cleared
Time = 61s: I add an item to my inventory
Time = 120s: My inventory array is cleared again
Time = 125s: I decide to wait until close to the three minute mark to loot
Time = 170s: I loot an item
Time = 180s: My inventory array is cleared again
I stopped here because I could see a pattern.
Now, is this an issue with my blueprint code or are arrays supposed to clear themselves every 60 seconds? I don’t think I have a variable set to 60 seconds anywhere in my code. And it seems odd that a variable would clear itself for no reason.
Aside
Also, after my inventory array is cleared, I’m still able to add items to it. I have an EventBeginPlay node attached to resizing my inventory array to 60. I’m guessing an array that is cleared retains its original length?
Still looking for help on this. My inventory array is a global variable in my Player Controller class. I don’t know why it’s clearing itself every minute even if the player does nothing.
I attached a print string to my Player Controller’s EventBeginPlay node, and found that the inventory is only resized once.
I used “Make Array” to set an empty array to five strings of text. I had the strings printed to the screen every second. This array seems to last past 60 seconds.
I renamed my Inventory to InventoryRenamed and the issue still occurs.
I changed the inventory size to 10 from 60, and the issue still occurs.
I made a new level with just a plane to stand on, the player pawn, and some items to loot. The issue still occurs.
I think I’ve figured out what’s causing the problem. But I don’t have a solution yet.
I was assuming my ‘add to inventory’ function was adding a copy of the item to the inventory array. However, what actually happened was that my function added a reference to the item to my inventory array. And at the end of the function, the item (in the world) is deleted. Every 60 seconds, Unreal’s garbage collector finishes removing all references to the destroyed actor, which is what caused my inventory item references to disappear.
Ah, in that case you might want your actual inventory to hold not the object’s reference, but say a byte that would spawn that object whenever you actually need it it displayed and interacting in the world.
So you could pick up item, update inventory with that object’s array value, destroy work object, and then if you threw it back on the ground, it would call that array member, perhaps run through a switch on enum, and spawn the correct item.
If the item had a number of stats on it, you could contain those stats in other arrays that would correspond to the same index as the item and would run the range of options that your item could have. You could even make a struct for each item type which would contain all the possible stats that an item could have.
This could also allow you to draw on those arrays for equipping and other similar functions without requiring the actual item.
But that is one way to do it. Probably dozens of ways to run an inventory and solve your current problem, including some that keeps the object around.
Structs seem very limited compared to blueprints however. I have a hierarchical item system in mind where every item in game inherits from a master blueprint with stats like damage, value, random magic effects, durability, level requirement.
Variations of an item would be child blueprints. Damage, magic effects and name need to be able to be randomized and generated at runtime a la Diablo and Borderlands. I was hoping to save the save random seed to regenerate the item when moving it from the world to the inventory.
It seems difficult to replicate that with just structs.
I wonder what the performance would be if I just kept the item actor blueprints in the world but hidden.
You can use the base item/object to transfer/create that information, I am just saying when you pick it up, take all the information, store it in a struct that is then stored in your inventory array, and then destroy the object.
The struct could store specific info such as 10 Strength, 5 Intelligence, Modifier X, Y, and Z, etc. Or you could do multiple structs, one for base stats, one for special item abilities, etc.
If you want the item in the world again, get it’s type and any other key information from your struct(s), then pump all your stats back into it, and release/spawn it into the world(such as equipping it or dropping it).
IE expose all the variables on your item BP’s, and you can dump your struct back into it as you spawn it. Keep all the pertinent information around without having to hide an object somewhere.
You wouldn’t even have to spawn the object to equip it, just move the struct information over to your character and spawn a model for your character to swing around.