- Home /
List Emptying Itself?
I'm currently making an inventory system and I've ran into a problem with a GameObject list which I've used to keep track of my items. I'm receiving the error message "ArgumentOutOfRangeException: Argument is out of range. Parameter name: index" when I call my method DropItem() from an OnClick() event from a button. This happens despite having called another method called PickUpItem() which adds a GameObject to my list. I've tried troubleshooting and had my List's count printed out to console when calling these methods. 1 is printed in the console when the PickUpItem() method is called (as expected), however when I call the DropItem() method 0 is printed to console and I receive the the error mentioned above.
The methods mentioned above (and another one being called in PickUpItem()):
public void DropItem(InventoryItem itemToDrop) {
print(inventory.Count);
if (inventory[itemToDrop.GetIndex()] != null) {
Instantiate(inventory[itemToDrop.GetIndex()], transform.position, transform.rotation);
Destroy(itemToDrop.gameObject);
inventory.Remove(inventory[itemToDrop.GetIndex()]);
}
else {
Debug.LogError("Inventory(" + this.GetInstanceID() + ") does not contain and cannot drop " + itemToDrop.name + ".");
}
}
public void PickUpItem(Item itemToPickUp) {
if (isPlayer && !isOpen) {
inventory.Add(itemToPickUp.gameObject);
Destroy(itemToPickUp.gameObject);
UpdateContents(itemToPickUp);
print(inventory.Count);
}
}
void UpdateContents(Item newItem) {
GameObject newInventoryItem = Instantiate(inventoryItemPrefab);
newInventoryItem.transform.SetParent(inventoryItemsPanel.transform, false);
newInventoryItem.GetComponent<InventoryItem>().SetIndex(inventory.IndexOf(newItem.gameObject));
newInventoryItem.name = newItem.itemName;
foreach(Transform child in newInventoryItem.transform) {
if (child.GetComponent<Text>() && child.name == "Name") {
child.GetComponent<Text>().text = newItem.itemName;
}
else if (child.GetComponent<Text>() && child.name == "Type") {
//child.GetComponent<Text>().text = newItem.type; Item class currently has no "type" variable
}
else if (child.GetComponent<Text>() && child.name == "Value") {
child.GetComponent<Text>().text = newItem.value.ToString();
}
}
}
The source is slightly confusing, but arent you destroying the item before you can actually remove it from your list?
Answer by DiegoSLTS · Aug 09, 2016 at 12:01 PM
You're adding the item object to the List and then destroying it. It prints 1 in the console because unity delays the destruction of objects until the end of the frame. You have to store something different on the inventory, like only the type of the power or maybe a more complex struct if you need more Info. So, when you pickup the item you store a new instance of some data struct and destroy the object, and when dropping it you remove the data and instantiate a new item.
Sorry for the late reply, but I have tried your suggestion out. I commented out both of the Destroy() calls in the pick up and drop methods to see if destroying the GameObject was causing the problem, but I still receive the same error. Aren't the items added to the list separate from the actual objects in the scene? Because if deleting the gameObject was the issue wouldn't I be receiving an error more like "The object of type 'GameObject' has been destroyed but you are still trying to access it" rather than the one I'm getting?
It looks like you have 2 problems then, the object begin destroyed after adding it to the inventory, and the inventory being empty when you call DropItem.
I'm not sure what you meant by the objects added to the list being "separate" from the actual objects in the scene. If you write...
inventory.Add(itemToPick.gameObject)
... you're just adding a reference to the object in the inventory, it's just a reference to the object instance, the same instante that's on the scene. Whatever you do to itemToPick.gameObject will be visible whenever you use a reference to that object.
Anyway, you're right, this is not the cause of your error. There's no way a list will delete it's content just by itself, if it's empty you're removing things somehow.
Are you switching to another scene? Do you have more code that access the inventory? Are you destroying the object or the component that has the inventory script attached? The inventory is a standard List object?