NullReference issue in Unity C#

Hi all - I’m having issues with a high-score table script. I’ve spend ages looking for a solution, please help…

public class HighscoreTable : MonoBehaviour
{
    private Transform entryContainer;
    private Transform entryTemplate;

    private void Awake()
    {
      
        entryContainer = transform.Find("highscoreEntryContainer");
        entryTemplate = entryContainer.Find("highscoreEntryTemplate");

        entryTemplate.gameObject.SetActive(false);

        float templateHieght = 30f;
        for(int i = 0; i < 10; i++)
        {
            Transform entryTransform = Instantiate(entryTemplate, entryContainer);
            RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
            entryRectTransform.anchoredPosition = new Vector2(0, -templateHieght * i);
            entryTransform.gameObject.SetActive(true);

            int rank = i + 1;
            string rankString;
            switch (rank)
            {
                default:
                    rankString = rank + "TH"; break;

                case 1: rankString = "1ST"; break;
                case 2: rankString = "2ND"; break;
                case 3: rankString = "3RD"; break;
            }
          
            Debug.Log(entryTransform.Find("posText"));
          
            entryTransform.Find("posText").GetComponent<Text>().text = rankString;

            int score = Random.Range(0, 10000);

            entryTransform.Find("scoreText").GetComponent<Text>().text = score.ToString();

            string name = "AAA";

            entryTransform.Find("nameText").GetComponent<Text>().text = name;

        }
    }
}

the entryTransform.Finds keep returning NullReference!

How do i add tags?

Thanks!

break it down and start logging to figure out what is null.

  1. does the .Find call returns a null or does the .GetComponent call returns a null?
  2. does entryTransform have a child name X while searching?
  3. is entryTransform the transform you think it is?

etc.

Cheers! I am debugging now. FYI - I did not write the code myself:

Okay, I think progress is being made.

Debug.Log(entryTransform.Find("posText"));

Debug.Log(GetComponent<Text>());

Both returned null. The entryTransform appears to be the issue, I think.

The attached image is my Hierarchy in game.

Transform entryTransform = Instantiate(entryTemplate, entryContainer)

This line is accurately working but i see two sets of posText, scoreText & nameText, etc. is that the issue, even though one set is greyed out?

6898343--807287--Example4.jpg

You should NEVER spend ages looking for this.

The answer is always the same… ALWAYS. It is the single most common error ever.

Don’t waste your life spinning around and round on this error. Instead, learn how to fix it fast… it’s EASY!!

Some notes on how to fix a NullReferenceException error in Unity3D

  • also known as: Unassigned Reference Exception
  • also known as: Missing Reference Exception
  • also known as: Object reference not set to an instance of an object

http://plbm.com/?p=221

The basic steps outlined above are:

  • Identify what is null
  • Identify why it is null
  • Fix that.

Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.

This is the kind of mindset and thinking process you need to bring to this problem:

https://discussions.unity.com/t/814091/4

Step by step, break it down, find the problem.

1 Like

Thanks yous for the links and advice. Believe it or not, this is my first major stumbling block since using Unity 4 months ago. quite frustrating.

Anyway, I performed a Debug.Log(entryTransform); at line 22 and the console returned:

highscoreEntryTemplate(Clone) (UnityEngine.RectTransform)
UnityEngine.Debug:Log (object)
HighscoreTable:Awake () (at Assets/Scripts/HighscoreTable.cs:26)

This tells me that entryTransform exists and is being cloned. That object has three children posText, scoreText & nameText that is what the .Find is trying to find. But there are two sets of each, the template is being deactivated per the void awake method, and its clones are being instantiated correctly.

The children have text components called posText, scoreText & nameText so there issue must be around there?

  1. The (entryTransform.Find(“posText”) returns the null
  1. Yes, child gameobjects called posText, scoreText & nameText are all instantiated as the entryTransform’s children per the prior images uploaded
  2. Yes, the entryTransform is a clone of the entryTemplate, placed into the entryContainer per the below line
    Transform entryTransform = Instantiate(entryTemplate, entryContainer);

Any suggestions on where to go from here?

Make a piece of code that lists all the children’s names right before you try to Find() them

for (int i = 0; i < TR.childCount; i++)
{
  Debug.Log( TR.GetChild(i).name);
}

PROVE to yourself that it is there.

(Replace TR with whatever Transform you’re searching)

You have GOT to be the mad scientist and prove to yourself at each stage (via a completely different mechanism) that what you are doing is valid. Otherwise you’ll spin forever thinking “But this should be valid!” when in fact it isn’t.

2 Likes

Glad EdoExpression moved this here from the Input System forum. Kurt-Dekker is giving you good advice. It’s pretty much the same advice I gave you in the Input System forum. Unfortunately, you kind of ignored it. I said you should try running this:

public class HighscoreTable : MonoBehaviour
{
    private Transform entryContainer;
    private Transform entryTemplate;

    private void Awake()
    {
        entryContainer = transform.Find("highscoreEntryContainer");
        entryTemplate = entryContainer.Find("highscoreEntryTemplate");
        Transform entryTransform = Instantiate(entryTemplate, entryContainer);
        entryTransform.Find("posText").GetComponent<Text>().text = rankString;
    }
}

But, for some reason, you ran a much longer, oddly edited version instead (see picture).

I told you bugs like this are pretty easy to solve. Kurt-Dekker said, “You should NEVER spend ages looking for this.” We’re both right. These are easy problems to solve if you use the suggestions you are getting. Kind of up to you if you do, but that’s how you find them.

2 Likes

Thanks - I’m up for the investigative work!! Attached is the result of the code below:

for (int ii = 0; ii < entryTransform.childCount; i++)
{
  Debug.Log( entryTransform.GetChild(i).name);
}

I had to replace i with ii because I got an error on visual studios saying “CS0135 - A local or parameter named ‘i’ cannot be declared because the name is used in an enclosing local scope to define a local parameter”.

Interestingly, the error below states that Transform child is out of Bounds, clicking on the offending line leads to

Debug.Log(entryTransform.GetChild(i).name);

https://discussions.unity.com/t/659602 - this implies i may have two of the same scripts in my scene: I do not!

How do I check if the Transform child is out of Bounds?

6901886--808004--Example5.jpg

Excellent sleuthing… but keep going! NOTE: if your iterator is ii then you need to use ii, not i

:slight_smile:

1 Like

Thank you for your patience. I get an error saying “CS0103 The name ‘rankString’ does not exist in the current context”. Hence, i edited the scrip to try and include the definition of rankString. However using the principles you provided, i tested the following code:

public class HighscoreTableTest : MonoBehaviour
{
 
    private Transform entryContainer;
    private Transform entryTemplate;

    private void Awake()
    {
        entryContainer = transform.Find("highscoreEntryContainer");
        entryTemplate = entryContainer.Find("highscoreEntryTemplate");
        Transform entryTransform = Instantiate(entryTemplate, entryContainer);
        string name = "AAA";

        entryTransform.Find("nameText").GetComponent<Text>().text = name;
    }
}

The result was NullReference exception. the offending line was

entryTransform.Find("nameText").GetComponent<Text>().text = name;

This makes me therefore question the entryTransform but I’ve already shown it and its children are correct??

Of course! Trying now…

just pointing out that you’re using i instead of ii both in the GetChild(i) and in the loop statement incrementor (int ii = 0; ii < entryTransform.childCount; i++)

Unity keeps crashing when i enter the code

for (int ii = 0; ii < entryTransform.childCount; i++)
            {
                Debug.Log(entryTransform.GetChild(ii).name);
            }
{/CODE]

if i remove the above, it works fine. What could cause that?

ii stays at 0 so it’s an infinite loop.

2 Likes

This has to be ii as well, all three places. :slight_smile:

1 Like