Odd Null Exceptions

I have an array of players using tags:

GameObject[ ] players = GameObject.FindGameObjectsWithTag (“Player”);

Each frame I loop through them.
for (int i=0; i<players.Length; i++) {}

Sometimes, the engine will throw a null exception, most of the time it won’t. Just to make sure the players were instantiating before this had time to hit, I made sure I instantiated this object as well, and I did it after the player instantiate.

Even if script execution order was the problem, it shouldn’t be firing a null exception every single frame. Am I doing something obviously wrong?

Where does this happen:

GameObject[] players = GameObject.FindGameObjectsWithTag ("Player");

And where does this happen: (I’m guessing Update())

for (int i=0; i<players.Length; i++) {}

What code is inside of your curly braces - I doubt you do nothing in your loop.

Do you have a log from when the NullException occurs?

Code snippits are notoriously difficult to troubleshoot. It’s better if you can include the entire script. If you do post more code, please use code tags.

1 Like

I can’t post the entirety of the code due to NDA. There is no need however, as this is where the null exception occurs:

if(players[i].gameObject.GetComponent<SomeScript>().someBool == true) {

99% of the time it will execute without a hitch. 1% of the time I will get a Null Exception.

I’ve tossed this in the for loop before that line:

if(players[i] != null && players.Length != 0) {

And that didn’t help. I figured I would try it anyhow.

I’ve consolidated this with the movement code in FixedUpdate and moved it out of Update to see if that resolves the issue. It’s hard to tell though because of how sporadic it is.

From the looks of it you are trying to access a script that may not exist for that GameObject. You need to make sure the script is on the game object before you try to access it, because it may not have it. Therefore GetComponent will return null. Try something like this:

SomeScript temp = players[i].gameObject.GetComponent<SomeScript>();
if (temp != null) {
    // Do what you need here
}

EDIT: Also, FixedUpdate and Update should not affect how this code is ran. The only difference between these two functions (By my knowledge) is when they are ran. Also If this code is in an Update function I would recommend finding a new way to store the items in your array because GetComponent can slow the system in large numbers. Might I suggest storing the scripts you need in the array and if you ever need the GameObject the script is attached to, you can do something like this:

script[i].gameObject

Thanks for the input!

The main reason I moved it to FixedUpdate was for the reason you mentioned above. If I am correct, FixedUpdate only loops 50 times a second, which is less than what the overall game is running. I figured that would be more cost efficient. I went ahead and dropped this in my check:

if(players[i].GetComponent<SomeScript>() != null && players.Length != 0) {

It shouldn’t be doing it however, because I instantiate the players first, and then instantiate this object. There are only (up to) 4 players, and each on is hand instantiated, and they do not disappear through the course of play.

I will report in if it does it again.

I think the easiest way to get to the bottom of this mystery would be to use the debugger.

Wrap the suspect code in a try catch block, then place a break point in the catch code. You should then be able to inspect the player’s list and see which component is null.

try
{
  for (int i=0; i<players.Length; i++)
  {
    // ...
  }
}
catch (NullReferenceException e)
{
// breakpoint here
// & consider doing some logging
throw;
}

Not a bad idea to leave the try catch in for a while with the logging anyways. You could recursively write the properties of each of the player GameObjects to a Trace file to help narrow down difficult corner cases. For example, maybe one of the components on a player is removed under certain rare circumstances.

Oh hey! I forgot C# had try and catch. Thanks for that! I like to wrap just about every function in that when I work on POS systems, that way I don’t get calls about a new system crashing. Then I have the throw print to a log file.

I have 3 more for loops that have been plugging away nicely. I have not changed their scripts, or any script related to them. They simply loop for a few objects in the scene.

They are all now throwing null exceptions, and the game still works.

Here is an example of one of the loops that was working perfectly, and then just stopped for no reason. I commented the last one out, and even tried a foreach loop, it did the same thing.

//See if every token is in a select position, if so, show the match ready GUI.
        GameObject[] tempTokenArray = GameObject.FindGameObjectsWithTag ("Token");
        int tCount = 0;

        /*foreach (GameObject g in tempTokenArray) {
            if(g.GetComponent<selection_token>().isGrabbed == false) {
                tCount++;
            }
        }*/
      
        /*for (int i=0; i<tempTokenArray.Length; i++) {
            if(tempTokenArray[i].GetComponent<selection_token>().isGrabbed == false) {
                tCount++;
            }
        }*/

The only reason I can see for these to throw a NullReferenceException is if GetComponent<selection_token>() is returning null. Despite how unlikely you think it is, you must somehow have introduced some objects into your scene which have the tag “Token” but do not have a component “selection_token”.

If the bug is reproducible, you should have no trouble finding these objects with help from the debugger as described above. The difficult question is what to do with them once you’ve found them.