Search Unity

Question NullReferenceException: Object reference not set to an instance of an object

Discussion in 'Scripting' started by Juandapp, Aug 26, 2021.

  1. Juandapp

    Juandapp

    Joined:
    May 11, 2016
    Posts:
    53
    I forget in the interface, drag and drop objects or scripts. Is there any way to do it in code, and thus avoid that every time I forget or use a prefab, I do not get this warning? I wish I didn't have to drag and drop on the interface every time I create a level.

    I mean, you don't have to come here to add anything. Sorry, I don't speak English and I don't know if I make myself understood.

    What I want is to reference from the code and not from the interface
    upload_2021-8-26_10-18-30.png
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    No matter what route you go, you still have to have a way to reference something. While you can use something like FindWithTag, these are generally not the most optimized.

    But if you must use it, use it once to grab the object at the start of your scene. But the basic use case would be to set your gameobject with a tag that allows you to find it and then grab the Animator component from it and assign that to the Separador variable.
     
  3. diXime

    diXime

    Joined:
    Oct 2, 2018
    Posts:
    162
    Hello,
    When you're not absolutely certain something will never be null, you should always check for null when using something. I know, it's redundant but it will lead to errors such as this one if you're not checking for null.
    So, one of the ways would be
    Code (CSharp):
    1. if(separator == null)
    2.    Debug.Log("You forgot to drag the separator into the component!")
    Now if you don't want to drag and drop the components every time, it depends if the component is on the same GameObject or not.
    You can use
    separator = GetComponent<Animator>()

    if it's on the same GameObject. If it's not, you'd need a reference to the GameObject that holds the component.
    separator = referenceToGameObject.GetComponent<Animator>()

    The way you get that reference depends on many things, GameObject.Find() and methods like that are not recommended.

    If you don't want to need to add the component on the GameObject when you're using your component, you have two options:
    Code (CSharp):
    1. [RequireComponent(typeof(Animator))]
    2. public class GameManagerGUI : MonoBehaviour
    3. {
    4. // your class
    5. }
    that will make sure the component is properly attached to the GameObject. You'll then be able to GetComponent<Animator>() whilst being sure one is present.
    or create a new method in an extension class, such as this one that I made a while back:
    Code (CSharp):
    1. public static class GameObjectUtils
    2. {
    3.     public static T GetOrAddComponent<T>(this GameObject go) where T : Component
    4.     {
    5.         return go.GetComponent<T>() ? go.GetComponent<T>() : go.AddComponent<T>();
    6.     }
    7. // [...]
    8. }
    and using it the same way as GetComponent<MonoBehaviour>(), like that:
    separator = gameObject.GetOrAddComponent<Animator>()

    so that it will find for the component, and if not found, add it to the GameObject.
     
    Last edited: Aug 26, 2021
  4. Juandapp

    Juandapp

    Joined:
    May 11, 2016
    Posts:
    53
    Thank you all, @diXime ,what a beautiful answer, just what I want to do and study. I would like to start with what you say here:

    Initially I would like to apply that, then, it is easy when I look for a local component, but it is not easy when I look for an external component of another object, I would like to know, what would be the optimal alternatives in code, as optimal as dragging and dropping the referenced object.

    All your information has been valuable, I will study each point separately for my future projects, the one I need now is the one named above.