Search Unity

'Object reference not set to an instance of an object' even when it is

Discussion in 'Scripting' started by Gabe-Tucker, Jan 17, 2020.

  1. Gabe-Tucker

    Gabe-Tucker

    Joined:
    Nov 26, 2015
    Posts:
    94
    Code (CSharp):
    1. private List<AudioSource> ambienceSources = new List<AudioSource> { };
    2.  
    3. if(GameObject.Find(ambienceName + "Amb").GetComponent<AudioSource>())
    4. {
    5.      Debug.Log("FOUND IT!");
    6. }
    7. ambienceSources.Add(GameObject.Find(ambienceName + "Amb").GetComponent<AudioSource>());
    Hey! My code prints "FOUND IT!" then proceeds to give me the error,
    NullReferenceException: Object reference not set to an instance of an object
    . This does not make any sense to me. Any ideas as to why the if statement can find the AudioSource if I'm getting this error that says it doesn't exist? Thanks in advance!
     
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,325
    You might also get a NullReferenceException if the ambienceSources list is null or if the GameObject / component with the method has been destroyed.

    Try something like this:

    Code (CSharp):
    1. private void Test()
    2. {
    3.     Debug.Log("this exists: " + (this != null));
    4.     Debug.Log("ambienceSources exists: " + (ambienceSources != null));
    5.  
    6.     var ambience = GameObject.Find(ambienceName + "Amb");
    7.     Debug.Log("ambience exists: " + (ambience != null));
    8.    
    9.     ambienceSources.Add(ambience.GetComponent<AudioSource>());
    10. }
     
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,325
    Also make sure that your script asset name perfectly matches the name of your MonoBehaviour class. That could also cause a NullReferenceException even if the component is never destroyed, since the component is not in a valid state.
     
  4. Gabe-Tucker

    Gabe-Tucker

    Joined:
    Nov 26, 2015
    Posts:
    94
    Hey there! Thanks for the help. This has helped me identify the problem. I uploaded a picture of the output, and here's the code that produced it.
    Code (CSharp):
    1. for (int i = 0; i < dataClasses.AmbienceList.Count; i++)
    2. {
    3.        Debug.Log(i);//0
    4.  
    5.        string ambienceName = dataClasses.AmbienceList[i].ambienceName;
    6.  
    7.        ambienceLayers.Add(GameObject.Find(ambienceName));
    8.        
    9.        Debug.Log("this exists: " + (this != null));//1
    10.        Debug.Log("ambienceSources exists: " + (ambienceSources != null));//2
    11.  
    12.        var ambience = GameObject.Find(ambienceName + "Amb");
    13.  
    14.        Debug.Log("ambience " + ambienceName + "Amb exists: " + (ambience != null));//3
    15.  
    16.        ambienceSources.Add(ambience.GetComponent<AudioSource>());
    17. }
    Given this code, the output makes no sense! The second loop prints Debug.Log 0 and 3, but not 1 or 2 like the first one. How does this happen? That would explain the error if it's skipping over a portion of the code. Thank you!!
     

    Attached Files:

  5. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,325
    You're not seeing all the log messages because "Collapse" mode has been enabled in your console window. This causes all identical log messages to get merged into only one entry.

    From the log entries we can see that the NullReferenceException is caused by GameObject.Find("TorchesAmb") returning null. So no GameObject with such name exists in the scene.

    Is there a reason by the way why you're using names to find the audio sources instead of just adding direct references to them in the inspector? Using direct references is less error prone since the references won't break even if you rename the targets, and you can see it easily in the inspector if a referenced target has been removed from the scene.
     
    Gabe-Tucker likes this.
  6. Gabe-Tucker

    Gabe-Tucker

    Joined:
    Nov 26, 2015
    Posts:
    94
    You saved me, it was me naming the GameObject "TorchAmb" rather than "TorchesAmb" that got me :) Thanks so much for the help! And yeah, the reason I'm using strings rather than direct references is because I want to be able to set the object names once in the prefab holding the script, as opposed to each time in each scene which seems redundant. Thanks so much, it's working now. Again, thanks for the help! :)
     
    SisusCo likes this.