Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

NullReferenceException bug?

Discussion in 'Scripting' started by emilianop, Sep 28, 2014.

  1. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    I get the following error:
    NullReferenceException: Object reference not set to an instance of an object

    Apparently coming form this part of the code:
    Code (csharp):
    1.  
    2.   List<GameObject> tempList = new List<GameObject>( GameObject.FindGameObjectsWithTag("Enemy") );
    3.  
    4.   if( tempList.Count>0 )
    5.   {
    6.     foreach(var e in tempList)
    7.     {
    8.       if (e.GetComponent<EnemyController>().enemyIsVisible)
    9.         enemyList.Add(e);
    10.     }
    11.   }
    12.  
    The weird thing is that if I close Unity and restart, the error is gone!
    This is always the case for that line (8 in the snippet above), it randomly errors up, I reboot unity, it's gone...

    Sounds legit?
     
  2. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    Perhaps some dead enemy got deleted from when you add to the list to when you use it. :)
    Just check for null: if(e != null && e.GetComponent<EnemyController>().enemyIsVisible)
    If not enough check for null in GetComponent too (but it's more weird).
     
    Last edited: Sep 28, 2014
  3. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    I'm guessing you have a GameObject tagged "Enemy" somewhere that does not have an Enemy Controller script on it.
    Code (csharp):
    1. foreach(var e in tempList)
    2. {
    3.     if (e == null) continue;
    4.     EnemyController enemy = e.GetComponent<EnemyController>();
    5.     if (enemy == null || !enemy.enemyIsVisible) continue;  
    6.     enemyList.Add(e);
    7. }
    This version I would use if you want to know what's going wrong.
    Code (csharp):
    1. foreach(var e in tempList)
    2. {
    3.     if (e == null)
    4.     {
    5.         Debug.LogWarning("Received a null e");
    6.         continue;
    7.     }
    8.     EnemyController enemy = e.GetComponent<EnemyController>();
    9.     if (enemy == null)
    10.         Debug.LogWarning("Missing EnemyController on object " + e.name);
    11.     else if (enemy.enemyIsVisible)
    12.         enemyList.Add(e);
    13. }
     
    Fraconte likes this.
  4. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Thanks for that.
    I thought the same, but the error, when happening, starts popping up straight away after I play the game, so no enemy is dead yet... :)
    I did check for e!=null already, but didn't help.
     
  5. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Thanks Garth, I didn't think about mis-assigned tagging.
    I'll check that now and implements those checks as soon as the error pops up again!
     
  6. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Ok so... I used this one and after compiling and recompiling it finally triggered the bug.
    I've got a nice:
    The problem is that I have NO obj_enemy(Clone) in scene at the time the game starts!
    I'm instancing enemies with the following:
    Code (csharp):
    1.  
    2. public class EnemyInstancer : MonoBehaviour
    3. {
    4.   public  GameObject enemy;
    5.   private float  instantiateTimer = 7.0f;
    6.   void Start ()
    7.   {
    8.   }
    9.  
    10.   void Update ()
    11.   {
    12.     instantiateTimer -= Time.deltaTime;
    13.  
    14.     if( instantiateTimer<0 )
    15.     {
    16.       float rMin = 1f, rMax = 6f;
    17.       float xx  = Random.Range(rMin, rMax);
    18.       float yy  = Random.Range(rMin, rMax);
    19.       Vector3 pos = new Vector3(xx, yy, 0);
    20.  
    21.       GameObject enemyClone = (GameObject)Instantiate(enemy, pos, Quaternion.identity);
    22.  
    23.       enemyClone.GetComponent<EnemyAI>().spawnPosition = pos;
    24.  
    25.       instantiateTimer = 7.0f;
    26.     }
    27.   }
    28. }
    Meaning that it would take at least 7 seconds before the first enemy gets created, but the error is there since the first frame.
    Also, because when this error pops up, if I do NOTHING and just close and reopen unity, it goes away, I'm starting thinking there's some engine glitch with some non properly cleaned up garbage.

    I'm puzzled.... o_O
     
  7. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Are you sure the error occurs in this script? What happens in EnemyController/EnemyInteraction?
     
  8. Vipsu

    Vipsu

    Joined:
    Oct 8, 2012
    Posts:
    88
    You really should use more null-checks in your code, they will often tell you exactly where the problem is.

    For example you aren't checking if the enemy prefab is null, which is pretty bad as sometimes Unity just forgets resets components for some reason removing all attached scripts and prefabs from it.

    Secondly you aren't null-checking if the instantiated enemy prefab even contains EnemyAI script. You are just directly trying to access it with:

    try something like this. Following code has null-checks for literally everything. (It's a bit of an overkill but usually I put my lists behind C# Properties that do the null-checking and lazy initialization for me. )

    Code (CSharp):
    1. GameObject[] tempEnemyArr = GameObject.FindGameObjectsWithTag("Enemy");
    2.  
    3.         if (tempEnemyArr.Length > 0)
    4.         {
    5.             GameObject go;
    6.             for (int i = 0; i < tempEnemyArr.Length; i++)
    7.             {
    8.                 go = tempEnemyArr[i];
    9.  
    10.                 if (go == null)
    11.                 {
    12.                     Debug.LogError("Gameobject is null index: " + i );
    13.                     continue;
    14.                 }
    15.  
    16.              
    17.                 EnemyController ec = go.GetComponent<EnemyController>();
    18.              
    19.                 if (enemylist != null)
    20.                 {
    21.                     if (ec != null)
    22.                     {
    23.                         enemylist.Add(e);
    24.                     }
    25.                     else
    26.                         Debug.LogError("Enemycontroller notfound in " + go.name);
    27.                 }
    28.                 Debug.LogError("enemylist is null, probably not initialized!");
    29.             }
    30.      
    31.         }
    For me, this sort of behavior happens usually due to different script exception order.
     
  9. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    EnemyInteraction is pretty empty, exactly for the purpose of tracking this.
    Its Update() is just
    Code (csharp):
    1. void Update()
    2. {
    3.   findAllEnemies();
    4. }
     
  10. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Thanks Vipsu, I'll give it a go with your suggestions!

    Checking for more nulls is not a problem, I just don't understand how this might happen when there's no enemy instantiated whatsoever (i.e. at the very first frame of the game), that's all.

    Re: the EnemyAI script, I'm confident it's not about that, since this error was happening even when I have no EnemyAI at all...
     
  11. Vipsu

    Vipsu

    Joined:
    Oct 8, 2012
    Posts:
    88
    Well you are searching gameobjects by tag in your script so it will find all objects tagged Enemy in the scene weither it has EnemyAI or not. In your For loop you could debug.log the name of the object which causes the error.
     
  12. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Yep, yesterday I checked in case I had some other "enemy" tag wandering around, but there's no other object shading that tag in the whole scene.... also that wouldn't explain why the error goes away when I reboot Unity, would it?
    I'll double check again tonight.
     
  13. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Rebooting Unity clears the console. As you seem to get the errors during runtime, they won't be shown until you run the scene again. Errors that do not disappear when rebooting Unity or clearing the console manually are errors in your code that Unity detects during the import process.
     
  14. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    ...but I know that, that's the whole point of this thread if you read it since the beginning.

    My console is set to Clear every time I recompile, so each time I get such error if I flush the console and replay it pops up again, but if I close unity and reopen it without changing a single thing, it's gone.
     
  15. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    If you can replay the error, try putting a debug.break before the error or immediately after. When it break, right click on the enemy prefab in the project and select "Find references in scene". This way perhaps you can understand if there is anything in the scene that should not be there.
     
  16. emilianop

    emilianop

    Joined:
    Aug 16, 2014
    Posts:
    28
    Cool, thanks Fraconte, I'll try that as soon as it pops up again (hasn't happened since yesterday....)