NullReferenceException problem

i’m in the process of creating a basic chess game by testing the movement functionality of a cube and cylinder. Once the object is chosen(which turns red) and the user clicks on the floor the piece will move to where the user selected. if the object hits another object it will remove the non-colored object. the problem is these checks are done in the update function and once the object is destroyed the check of that option is then a null reference(it can’t check for a state if the object is destroyed). how will i ensure that a null reference exception does not happen (here’s the update function):

if(hit.collider.gameObject.name == “Cube”)
{
Cube.renderer.material.color = Color.red;
Cylinder.renderer.material.color = Color.white;

}

else if(hit.collider.gameObject.name == “Cylinder”)
{
Cylinder.renderer.material.color = Color.red;
Cube.renderer.material.color = Color.white;
}

else if(hit.collider.gameObject.name == “Floor” Cube.renderer.material.color == Color.red)
{
OnMouseDown(0);
}

else if(hit.collider.gameObject.name == “Floor” Cylinder.renderer.material.color == Color.red)
{
OnMouseDown(1);
}

if ( x != null ) {
  // do stuff with x
}

You can also “if ( x )” but that can be harder to read.

let me explain this in more detail. if i move the cylinder and it hits the cube the cube will disappear therefore there is no need for the second else if statement in my update function above.It is fine when i move the cube and it hits the cylinder, i can move the cube again and there are no problems. once the cylinder hit the cube and i want to move the cylinder again i cannot as an MissingReferenceException error occurs(mistake in the title) which refers to the second else if statement, how do i tell the engine to ignore that else if statement?

It appears like the code above is suppost to be in a OnCollisionEnter() function. However, your talking about the update function so I’m a little confused. Perhaps you can provide the full script. The update function, OnCollisionEnter function, and wherever the attacking chess peice uses Destroy() to get rid of the other. It would also help if the code was inside of a tag.

Once you’re out of testing, there won’t be two objects to check, there will be exactly one (the one which is selected). Unless you want to go through every piece every frame and check its renderer color.

Instead of manually checking each object every frame, just let the clicked-on piece notify script that piece is now the currently-selected piece.

for instance:

class MyScript : MonoBehaviour {
  public static Piece selectedPiece;
... 
  if ( selectedPiece ) {
    if ( clickedOnGround ) // stuff
  }
...
}
class Piece : MonoBehaviour {
  void ClickOn() {
    MyScript.selectedPiece = this;
  }
}

roger0, the code above is that of a raycast, it checks to see if it hits anything then it checks what it hits. i did not supply the raycast check above as this is not the problem i am having. there is a collision script which has the OnCollisionEnter() you describe, which destroys the object only if the object hitting it is coloured. Here is the select script which is placed on an empty gameObject which Checks for mouse clicks and moves the associated pieces:

#pragma strict
import System.Collections.Generic;
var Cube : GameObject;
var Cylinder : GameObject;
var arr : List.<GameObject> = new List.<GameObject>();
var myComponent : Component;


function Start()
{
	 arr.Add(Cube);
	 arr.Add(Cylinder); 
}


function Update ()
{
	if(Input.GetMouseButtonDown(0))
	{
		var hit : RaycastHit;
		var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		if(Physics.Raycast(ray, hit, 100.0))
		{
			Debug.Log(hit.collider.gameObject.name);
			
			if(hit.collider.gameObject.name == "Cube")
			{
				Cube.renderer.material.color = Color.red;	
				Cylinder.renderer.material.color = Color.white;
				
			}
			
			else if(hit.collider.gameObject.name == "Cylinder")
			{
				Cylinder.renderer.material.color = Color.red;
				Cube.renderer.material.color = Color.white;
			}
			
			
			else if(hit.collider.gameObject.name == "Floor"  Cube.renderer.material.color == Color.red)
			{	
				OnMouseDown(0);
			}
			
			else if(hit.collider.gameObject.name == "Floor"  Cylinder.renderer.material.color == Color.red)
			{	
				OnMouseDown(1);
			}		
	  }
	}
}	

function OnMouseDown(i : int)
{
		var hit : RaycastHit;
		var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		//Get the mouse position
	    var mousePosition : Vector3 = Input.mousePosition;
	
	    //Cast it into a ray
	    var screenRay : Ray = Camera.main.ScreenPointToRay( mousePosition );
	    
	    //Initializing some variables
	    var hitInfo : RaycastHit;
	
	    //Grab the information we need
	    Physics.Raycast( screenRay, hitInfo );
	
	    //And find the point of impact
	    var pointOfImpact : Vector3 = hitInfo.point;
	    
	    //Move the object in question
	    arr[i].transform.position = pointOfImpact;
	    arr[i].transform.position.y += 15;
		
	    arr[i].rigidbody.useGravity = true;
            arr[i].rigidbody.isKinematic = false;
}


The collison script of the cube which destroys any object it hits:

[CODE]

import System.Collections.Generic;

var Cylinder : GameObject;
var Cube : GameObject;
var Collids : Select;

function Start()
{
	 Collids = gameObject.Find("Selection").GetComponent("Select");
}


function OnCollisionEnter(col : Collision)
{
	if(col.gameObject.name == "Floor")
	{
		Debug.Log("Hit Floor");
	}
	
	else if(col.gameObject.name == "Cylinder"  Cube.renderer.material.color == Color.red)
	{
		Debug.Log("Hit Cylinder");
		Collids.arr.Remove(Cylinder);
		Destroy(Cylinder);
	}	

And Finally the Collision Script of the cylinder:

[CODE]

import System.Collections.Generic;

var Cylinder : GameObject;
var Cube : GameObject;
var Collids : Select;

function Start()
{
	 Collids = gameObject.Find("Selection").GetComponent("Select");
}


function OnCollisionEnter(col : Collision)
{
	if(col.gameObject.name == "Floor")
	{
		Debug.Log("Hit Floor");
	}
	
	else if(col.gameObject.name == "Cube"  Cylinder.renderer.material.color == Color.red)
	{
		Debug.Log("Hit Cube");
		Collids.arr.Remove(Cube);
		Destroy(Cube);
	}	
}

Its hard to get a grasp of the issue. Could provide a project file? If the project is huge, then try making a smaller version that is only narrowed down to the problem.

If you stick with this method - “Cube” and “Cylinder”, that is - eventually you’re going to have code that looks like this:

if ( collided == Pawn1  Pawn1.renderer.material.color == Color.red ) {
}if ( collided == Pawn2  Pawn2.renderer.material.color == Color.red ) {
}if ( collided == Pawn3  Pawn3.renderer.material.color == Color.red ) {
}if ( collided == Pawn4  Pawn4.renderer.material.color == Color.red ) {
}
.. .. ..

You absolutely do not want that.

You’re getting an NRE because you’re accessing Cylinder (or Cube) after destroying it.
As I said above, you can use nullable variables in if statements to test for null.

if ( Cylinder.renderer ) // causes null-ref; "Cylinder" is null

if ( Cylinder ) { // if Cylinder is null, skip this if
  if ( Cylinder.renderer. ~etcetera // does NOT cause null-ref, since the if prevents execution from reaching this line
}

OK i followed your suggestion but i instead used GameObject.find(“Name”), so i now have the following checks:

	if(GameObject.Find("Cube"))
			{
				if(hit.collider.gameObject.name == "Cube")
				{
					Cube.renderer.material.color = Color.red;	
					Cylinder.renderer.material.color = Color.white;
				}
				
				else if(hit.collider.gameObject.name == "Floor"  Cube.renderer.material.color == Color.red)
				{
					OnMouseDown(0);
				}
			}		
	
			if(GameObject.Find("Cylinder"))
			{
				if(hit.collider.gameObject.name == "Cylinder")
				{
					Cylinder.renderer.material.color = Color.red;
					Cube.renderer.material.color = Color.white;
				}
				
				else if(hit.collider.gameObject.name == "Floor"  Cylinder.renderer.material.color == Color.red)
				{
					OnMouseDown(1);
				}
			}
I first tested the movement of the cube and checking if the cube continued moving if the cylinder was destroyed, this works fine.
Then i tested  the cylinder, after the cylinder deletes the cube i try to move the cylinder i get an ArguementOutOfRangeException. This refers to my OnMouseDown() function which takes an int depending on the array of my gameobjects. e.g: OnMouseDown(0) means move the cube and OnMouseDown(1) moves the Cylinder. The removal of the cube appears to have decremented the int from 1 to 0. How do i solve this issue.

Problem Solved:

I added this code into after i find the cylinder:

[CODE]

if(GameObject.Find("Cylinder"))
			{
				if(hit.collider.gameObject.name == "Cylinder")
				{
					Cylinder.renderer.material.color = Color.red;
					Cube.renderer.material.color = Color.white;
				}
				
				else if(hit.collider.gameObject.name == "Floor"  Cylinder.renderer.material.color == Color.red)
				{
					if(GameObject.Find("Cube"))
						OnMouseDown(1);
					else
						OnMouseDown(0);
				}
		
			}

Thanks for your help Loius :)