NullReferenceException TextMeshPro But it shows its not null??

This is the relevant code

 targetText = thisUpgradeCanvas.transform.Find("TargetText").GetComponent<TextMeshProUGUI>();
  
void SetTextForWhoToAttack(int value)
    {
        switch (value)
        {
            case 0:
                targetText.text = "First"; // shows error
                break;
            case 1:
                targetText.text = "Last"; // shows error
                break;
            case 2:
                targetText.text = "Strong"; // shows error
                break;
            case 3:
                targetText.text = "Weak"; // shows error
                break;
            case 4:
                targetText.text = "Close"; // shows error
                break;
        }
    }

This shows that on start the code is referencing the text as it should


This shows the error that it is null even though it shows it is not null


This is the entire class code
```csharp
**__using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class CanvasController : MonoBehaviour
{
public GameObject upgradeCanvas;
GameObject thisUpgradeCanvas;
int attackIndex = 0;

HeroController heroController;

public TextMeshProUGUI targetText;

void Start()
{
    heroController = gameObject.GetComponent<HeroController>();
    thisUpgradeCanvas = Instantiate(upgradeCanvas);
    targetText = thisUpgradeCanvas.transform.Find("TargetText").GetComponent<TextMeshProUGUI>();
    thisUpgradeCanvas.SetActive(false);
}
public GameObject GetCanvas()
{
    return thisUpgradeCanvas;
}

public void SetCanvasActive(bool value)
{
    thisUpgradeCanvas.SetActive(value);
}

public void ChangeAttackIndexRight()
{
    if (attackIndex < 4)
    {
        attackIndex++;
        SetTextForWhoToAttack(attackIndex);
    }
    else
    {
        attackIndex = 0;
        SetTextForWhoToAttack(attackIndex);
    }
    SetState(attackIndex);

}
public void ChangeAttackIndexLeft()
{
    if (attackIndex > 0)
    {
        attackIndex--;
        SetTextForWhoToAttack(attackIndex);
    }
    else
    {
        attackIndex = 4;
        SetTextForWhoToAttack(attackIndex);
    }
    SetState(attackIndex);
}

void SetTextForWhoToAttack(int value)
{
    switch (value)
    {
        case 0:
            targetText.text = "First";
            break;
        case 1:
            targetText.text = "Last";
            break;
        case 2:
            targetText.text = "Strong";
            break;
        case 3:
            targetText.text = "Weak";
            break;
        case 4:
            targetText.text = "Close";
            break;
    }
}
void SetState(int value)
{
    heroController.SetState(value);
}

}**
**
```__**

When exactly did you take the screenshot showing the value of targetText in the inspector? In Start() its value gets overwritten to be the result of a Find() call (line 20), so if you took that screenshot in edit mode then its value is irrelevant. You’d need to check its value at runtime.

Also, check for any other code that could be modifying it.

Antistone… It is supposed to work this way where line 20 assigns the variable. I did not assign anything to it in the inspector. The screenshot was taken at runtime.

Is it possible that you have a second copy of this MonoBehaviour somewhere in your scene?

1 Like

Thanks for your response antistone… no there is no other script in the scene

Where does it show that targetText is ā€œnot nullā€ in your code? You never check. Debug.Log it to confirm.

1 Like

It is possible for your public methods which call SetTextForWhoToAttack to be called prior to the Start method. For example, if you Instantiate a prefab with this script attached, or add this component at runtime, and during the same frame you call SetTextForWhoToAttack, this will result in a null reference error because Start not be called until after the current frame ends and before the next frame starts.

Add a null check to SetTextForWhoToAttack, and return if null or go ahead and set targetText at that time. You should also investigate this by adding a Debug.Log statement to Start and another to SetTextForWhoToAttack to determine if Start is being called before or not.

Thanks for everyones help. It works now… unfortunately I’m not sure how it was fixed.

same thing happened to me and I couldn’t find any solution.
so I chose alternative way and it works. I don’t understand why :confused:

public TMPro.TextMeshProUGUI text;

public void Awake(){
// this is NOT WORKING but still you can check text is NOT NULL in Unity Inspector
// text = gameObject.transform.GetComponentInChildren<TMPro.TextMeshProUGUI>();

      GameObject textObj = this.gameObject.transform.GetChild(0).gameObject;
      text = textObj.GetComponent<TMPro.TextMeshProUGUI>(); // this WORKS
}

transform.GetChild(0) is giving you the first child of the game object that this script is attached to. I presume your hierarchy looks like this:

ObjectWithScript

  • ObjectWithText

ObjectWithScript does not have a text component. Trying to get such a component from it will not work.

ObjectWithText does have the component.

It appears you failed to do Step #1 of the only three steps that will fix this error.

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that

NOTE: please do not necro-post to 2019 threads because that is also not one of the three steps.

Presumably that is why the commented-out code is using GetComponentInChildren

1 Like

Oops. Hm, that’s strange, then!