MissingReferenceException

I keep getting an error whenever I press the “g” key that “The object of type 'GameObject has been destroyed but you are still trying to access it…”

I’m sure there’s a fairly simple fix to this. It says to check if null or not destroy the object, but I don’t know how to implement this in my code. Any ideas?

The error occurs at line 59 due to line 52’s calling of the method DropItem()

import System.Collections.Generic;

class CItem
{
	var name : String;
	var itemId : int;
	var obj : GameObject;
	var weight : float;
}

var inventory : List.<CItem> = new List.<CItem>();
var activeObject : int;
var maxItems : int = 5;
var pos : Vector2;
var size : float;
var spacing : float;
var hand : GameObject;
var dropPos : Vector3;

function Start () 
{

}

function Update () 
{
	
	activeObject = Mathf.Clamp (activeObject, 0, inventory.Count);
	
	if(Input.GetKeyDown("q"))
	{
		if(activeObject >= inventory.Count-1)
		{
			activeObject = 0;
		
		}else
		
			activeObject++;
	}else
	
	if(Input.GetKeyDown("e"))
	{	
		if(activeObject <= 0)
		{
			activeObject = inventory.Count-1;
		}else
			
			activeObject--;
	}
	if(Input.GetKeyDown("g"))
	{
		DropItem();
	}
	
}

function DropItem()
{
	inventory[activeObject].obj.SetActive(true);
	inventory[activeObject].obj.transform.position = dropPos + hand.transform.position;
	inventory[activeObject].obj.transform.parent = null;
	inventory[activeObject].obj.rigidbody.isKinematic = false;
	inventory.Remove(inventory[activeObject]);
}

function ItemPickup (item : GameObject)
{
		var newItem : CItem = new CItem();
		newItem.name = item.transform.parent.gameObject.name;
		newItem.obj = item.transform.parent.gameObject;
		newItem.weight = item.transform.parent.gameObject.rigidbody.mass;
		inventory.Add (newItem);
}

function OnGUI()
{
	for(var i : int = 0; i < inventory.Count; i ++)
	{
		if(activeObject == i)
		{
			GUI.color = Color.red;
		}
		else
			GUI.color = Color.white;
		
		GUI.Label (Rect(pos.x + (i * spacing) + 5, pos.y + 50, size, size/2), "" + inventory[i].name);
		GUI.Box (Rect(pos.x + (i * spacing), pos.y, size, size), "");
	}
}

Is the inventory empty?

function DropItem()

{

    inventory[activeObject].obj.SetActive(true);

    inventory[activeObject].obj.transform.position = dropPos + hand.transform.position;

    inventory[activeObject].obj.transform.parent = null;

    inventory[activeObject].obj.rigidbody.isKinematic = false;

    inventory.Remove(inventory[activeObject]);

}

this code only works once, after that you need to change activeObject index so it will no longer point to the index of the item you removed from your inventory.

try and reset to 0 each time you press to drop the selected item.

if(Input.GetKeyDown("g"))
    {
        DropItem();
        activeObject = 0;
    }

Even better would be to additionally modify your DropItem function to make sure your inventory List object contains a key that matches activeObject before attempting to access it. That way, even if the value somehow become invalid (such as dropping the last item) it wouldn’t throw an error.

Plz, never write ‘inventory[activeObject].obj.SetActive…’ you will get a lot of ecxeption because of this. Add some checks or rewrite your code in other way. Until you have not sure if inventory is not null and activeObject is not null and inventory[activeObject].obj is not null, every part of this sentence could lead to exception.

Patico, it doesn’t make a difference if I write it as inventory[activeObject].obj.active = true; or as I did in my current code. That is not where the exception error is and changing it doesn’t remove the error.

Glockenbeat, nope. I can visibly see the two items in my inventory.

ar0nax, I will try this ASAP and let you know if it worked :slight_smile:

wccrawford, I’m not exactly sure how I would go about this. What do you mean “contains a key”?

Hi, corinne44,
You misunderstand me. I mean there are a lot of elements that could be null. If any one of inventory, activeObject or obj will be null you will got an NullReferenceExcemtion or, probably MissingReferenceException.

It will be easier to find where is your error located, if you change this code

function DropItem()
{
    inventory[activeObject].obj.SetActive(true);
    inventory[activeObject].obj.transform.position = dropPos + hand.transform.position;
    inventory[activeObject].obj.transform.parent = null;
    inventory[activeObject].obj.rigidbody.isKinematic = false;
    inventory.Remove(inventory[activeObject]);
}

to this:

function DropItem()
{
	var inventoryObj = inventory[activeObject];
	if(inventoryObj != null)
	{
		var obj = inventoryObj.obj;

		if(obj != null)
		{
		    obj.SetActive(true);
		    obj.transform.position = dropPos + hand.transform.position;
		    obj.transform.parent = null;
		    obj.rigidbody.isKinematic = false;
		    inventory.Remove(inventory[activeObject]);
	    }
	    else 
	    	Debug.Log("inventory[activeObject].obj == null");
    }
    else 
    	Debug.Log("inventoryObj == null");
}

Or will use Specification pattern:

function DropItem()
{
	if(IsInvertoryObjectExists())
	{
	    inventory[activeObject].obj.SetActive(true);
	    inventory[activeObject].obj.transform.position = dropPos + hand.transform.position;
	    inventory[activeObject].obj.transform.parent = null;
	    inventory[activeObject].obj.rigidbody.isKinematic = false;
	    inventory.Remove(inventory[activeObject]);
	}
}

function IsInvertoryObjectExists() : bool
{
	if(inventory != null  activeObject != null)
	{
		if(inventory[activeObject] != null)
		{
			if(inventoryObj.obj != null)
				return true;
			else
				Debug.Log("inventory[activeObject].obj == null");
		}
		else 
    		Debug.Log("inventoryObj == null");
    }
    else 
    	Debug.Log("inventory or activeObject is null");

	return false;
}