Reputation: 416
When i pick a item in my scene, it calls the AddItem() method, and this method would add the item to an List and destroy the gameObject from the scene, but when i try to acess the gameobject in the list this error appears.
"MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it."
public class Inventory : MonoBehaviour
{
public List<GameObject> itemsGOInInventory = new List<GameObject>();
public void AddItem(GameObject itemToBeAdded)
{
itemsGOInInventory.Add(itemToBeAdded);
Destroy(itemToBeAdded);
}
public void FindItem(string name)
{
foreach (GameObject item in itemsGOInInventory)
{
if (item.GetComponent<Item>().itemName == "pistol")
{
Instantiate(item.GetComponent<Item>().itemObject, this.transform);
}
}
}
}
Upvotes: -1
Views: 2104
Reputation: 1268
You say that you destroy GameObject once its picked up. Once destroyed, it doesn't exist and all references to the GameObject are null. It is a bad idea to keep list of gameobjects in your case. Instead, you should have a model class for inventory items.
public class InventoryItem
{
string name;
string description;
string spritePath;
// other variables
}
You should create a separate class to represent the InventoryItem in the scene. You could have something like this on your gameobjects:
public class InventoryItemView : MonoBehaviour
{
public InventoryItem item;
// ...
}
Now put the item script on 'items' in your scene. Whenever you pick an item, get the InventoryItem script from the gameobject and add it to the list of InventoryItems in your Inventory. Then destroy the gameobject. Now even when your gameobject is destroyed, you have your InventoryItem object.
public class Inventory : MonoBehaviour
{
public List<InventoryItem> itemsGOInInventory = new List<InventoryItem>();
public void AddItem(GameObject itemToBeAdded)
{
itemsGOInInventory.Add(itemToBeAdded.GetComponent<InventoryItemView>().item);
Destroy(itemToBeAdded);
}
//...
}
You might want to check for whether the GameObject has the InventoryItemView script on it.
Ideally your inventory class should not be MonoBehaviour, a serializable class would have sufficed, but that is off topic.
Upvotes: 1
Reputation: 929
Once you destroy the gameobject, its gone.
What you can do is hold a reference to that object and then store it somewhere and make it invisible. Its called object pooling.
Unity has a tutorial on this here: https://unity3d.com/learn/tutorials/topics/scripting/object-pooling
You need to set the gameobject SetActive to false or use other means to make it invisible. https://docs.unity3d.com/ScriptReference/GameObject.SetActive.html
You already have the list of objects, so instead of Destroy(), use SetActive(false);
itemToBeAdded.SetActive(false);
Hope this helps.
Upvotes: 3