- Home /
NullReferenceException in my cheat code?
I am trying to add a cheatcode to my game. This is the script controlling the cheatcode
using UnityEngine;
using System.Collections;
public class CheatCodeListener : MonoBehaviour
{
private string[] cheatCode;
private int index;
private GameObject asteroid;
private DestroyByContact destroyByContact;
void Start()
{
cheatCode = new string[] { "c", "j", "b", "r", "u", "e", "l"};
index = 0;
asteroid = GameObject.FindGameObjectWithTag("Asteroid");
destroyByContact = asteroid.GetComponent<DestroyByContact>();
}
void Update()
{
if (Input.anyKeyDown)
{
if (Input.GetKeyDown(cheatCode[index]))
{
index++;
}
else
{
index = 0;
}
}
if (index == cheatCode.Length)
{
print("Cheatcode entered");
destroyByContact.scoreValue = 100;
index = 0;
}
}
}
Here is the DestroyByContact script referenced in the CheatCodeListener script
using UnityEngine;
using System.Collections;
public class DestroyByContact : MonoBehaviour
{
public GameObject explosion;
public GameObject playerExplosion;
public GameObject sSExplosion;
public int scoreValue;
private GameController gameController;
void Start ()
{
scoreValue = 10;
GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
if (gameControllerObject != null)
{
gameController = gameControllerObject.GetComponent <GameController>();
}
if (gameController == null)
{
Debug.Log ("Cannot find 'GameController' script");
}
}
void OnTriggerEnter(Collider other)
{
if (other.tag == "Boundary")
{
return;
}
Instantiate(explosion, transform.position, transform.rotation);
if (other.tag == "Player")
{
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver ();
scoreValue = 0;
}
if(other.tag == "ProtectMe")
{
Instantiate (sSExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver ();
scoreValue = 0;
PlayerController.canControl = false;
PlayerController.speed = 0;
}
gameController.AddScore (scoreValue);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
In my game, I have prefab asteroids, which are tagged as Asteroid, and these have the DestroyByContact script on them. With these scripts, I got an error when I started the game, NullReferenceExeption. I figured that this is because the asteroids are spawned a few seconds after starting the game, and there are no objects in the hierarchy with that tag at start. So I made an empty game obejct, tagged it Asteroid, and the game plays. But when I type "cjbruel" (the cheatcode) I get a NullReferenceExeption error in the destroyByContact.scoreValue = 100;
line of the CheatCodeListener script. I hope I have explained this well enough... Any idea how to deal with this?
Answer by rutter · Jun 04, 2014 at 05:57 AM
It's important to remember that GetComponent
returns null if no such component is attached.
So, this line:
destroyByContact = asteroid.GetComponent<DestroyByContact>();
The line itself appears basically fine, but you're running into some problem, such as:
GameObject.FindGameObjectWithTag("Asteroid")
might return something other than what you expect. Are there multiple objects with that tag?The
asteroid
GameObject might not have aDestroyByContact
component attached. Could it be attached to a parent or child? You can also use GetComponentInChildren.Possible but unlikely: by the time the cheat code is called, the
DestroyByContact
you referenced has been destroyed, or the reference has been changed by some code not seen here.
Let me explain a little bit better. $$anonymous$$y game is a personalized version of the Space Shooter tutorial. At the start of the game, there are no objects tagged Asteroid. They are all spawned after the game is started. But with the code I posted, that gave my a NullReferenceException because the script couldn't find anything with that tag. To fix that, I put an empty gameobject in and tagged it as Asteroid. That fixed the first NullReference. I don't think your second statement is a problem, because the asteroid does have a child attached but the parent has both the script and the tag. Regarding the third, it may be a possibility. Because of the pace of the game, the only time you have enough time to enter the cheatcode is between waves of asteroids. At that time, all asteroids have been destroyed, but there is still the empty object with the tag. Does this clarify?
I understand what you've written, but it doesn't change my answer aside from adding some more specific information. From the moment your GetComponent
looks up the wrong object, there's no easy way to recover.
The fix you've tried does avoid a null reference exception, but it sounds like it silently sets up a time bomb, ins$$anonymous$$d.
Are there multiple objects tagged with "asteroid"? If so, you might rather search using FindGameObjectsWithTag. It will return an array containing every active GameObject with the requested tag. You can then loop through the array.
If the object(s) you're looking for don't exist at the time of the search, how do you expect to find them? You'll need to delay the search until they do exist. You could use script execution order to make sure that this search executes after the rest of the scene has initialized. You could wait until the cheat code is entered to actually perform the search.
Okay sorry for the delay... I've been working on other things.
I changed the setup of the script, so that ins$$anonymous$$d of defining all of the scripts and gameobjects and the like in Start{}, I do all that in another function which is called when the cheatcode is entered.
I was able to remove the object which you so poetically defined as a "time bomb". Which I have to agree with. I also shortened the cheatcode to just C for testing purposes.
To my excitement, it works! Pressing C makes the first object found with the Asteroid tag worth 100 points.
I think I explained it already, but my asteroids come in waves of 10, with a few seconds pause between waves. The asteroids are simply copies of a prefab asteroid. The prefab is tagged as Asteroid. But entering the cheatcode only changes the first asteroid's value. The others are all still worth 10 points. Entering the cheat between waves, when no asteroids are in the scene yet causes a NullReference error.
So I'm making progress, but I'm not where I want to be yet. However, this particular question has been answered as far as I am concerned. I'll take the scripts as they have been changed now, and start a new question to work out the kinks. @rutter Thanks for your help!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
NullReferenceException 1 Answer
An object reference that seems pretty set-to-an-instance-of-an-object to me 0 Answers
NullReferenceException error in an array of objects 0 Answers