Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

NullReferenceError with Text

Discussion in 'Getting Started' started by Deleted User, Dec 26, 2018.

  1. Deleted User

    Deleted User

    Guest

    I know when watching Swords and Shovels, if I remember, generally this error appeared when a GameObject was not sent to a public inspector field.



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class Chris : MonoBehaviour
    7.  
    8. {
    9.     private Text WhatChrisSays;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         WhatChrisSays = gameObject.GetComponent<Text>();
    15.         WhatChrisSays.text = "Hello Kevin.";
    16.     }
    17.  
    18. }
    The thumbnail shows my scene with the problem. The game shows the text "this is what Chris says", not "Hello Kevin."
     

    Attached Files:

  2. Which object you have the "Chris" script on? If it is a parent of the Text, you can try to use GetComponentInChildren instead of the GetComponent, but be aware that it will return with only one (the first it founds) in case you will have more text on it.
    Or alternatively you can do this way:
    Code (CSharp):
    1. [Serializable]
    2. private Text WhatChrisSays;
    Open up the GameObject which contains the Chris script in the inspector and drag and drop the Text game object on it. In this case you can remove the getComponent line entirely.
     
    Schneider21 likes this.
  3. Deleted User

    Deleted User

    Guest

    The Chris script (yes I took my time :) I didn't think Serializable was the only way... or safest way to do this ) is on Chris Controller in the ChrisScene.
    Also private does not allow the inspector to be used. I'll look at Serializable on the manual pages before I ask again.
     
  4. Deleted User

    Deleted User

    Guest

    I've only just noticed ChrisController is a child of Canvas. Would that mess things up?
     
  5. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    In object-oriented programming, it's good practice to encapsulate your classes to avoid data being changed accidentally. To facilitate this, you can use accessors to set how variables and properties can be accessed.
    public - Any code with a reference to this class can read or modify this value.
    private - Only methods within this class can read or modify this value.

    Unity uses these accessors to decide what to display in the editor. By default, public variables are visible and can have their values changed via the Inspector. This goes against good coding practice, though, so a common thing to do once you're looking to write cleaner code is to make properties private and mark them with the [SerializeField] decorator to tell Unity to show it in the Inspector and allow it to be modified from there.

    - - -

    As far as your question goes, whether the element is a child of a Canvas shouldn't matter. GetComponent<T> will find components of type T on the GameObject from which its run regardless of where it is in the tree. There's gotta be something else going on here.
     
  6. Oh, sometimes I'm dumb like hell, I was thinking of SerializeField and I wrote Serializable.

    Sorry @thenewkgb82 sorry about that, my mistake.
     
  7. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    I get them confused all the time. In fact, I actually wrote out System.Serializable but had to check to see if that was it or not.

    For the curious, [System.Serializable] is the tag used on custom classes to make them visible in the Inspector. So same idea, but for a whole class, versus exposing a single private field with [SerializeField].
     
  8. Yeah, in the mean time I'm working on my own code and I'm working on special ScriptableObjects with custom classes so I use both a lot. Probably that was the last one I used when I wrote the above post. :D
     
    Schneider21 likes this.
  9. Deleted User

    Deleted User

    Guest

    So the code above should work?
     
  10. Deleted User

    Deleted User

    Guest

    Even with SerialField in place the text still says "this is what Chris says".
    I think in times like these, I need to do something else to work around this and figure out more about Unity. I'll come back to this another time!
     
  11. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    The way you have it written, the code should work if the script is attached to the object you have selected in the screenshot. It won't work if you have it on, say, the ChrisTextPanel object. The reason being that GetComponent only looks for components on the current GameObject.

    If you want to have the script attached elsewhere, you'll need to modify it a bit using the methods @Lurking-Ninja described.