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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Trying to make if(thing == null)

Discussion in 'Scripting' started by kittik, Nov 17, 2015.

  1. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    I have added doors into my game, which I want to open once all of the enemies within a room have been killed.

    When an enemy is killed, they are destroyed, so I tried the following -
    Code (CSharp):
    1. public GameObject[] enemy;
    2. public bool isDone = false;
    3.  
    4. void Update ()
    5.     {
    6.         if(enemy == null && isDone == false)
    7.         {
    8.             isDone == true;
    9.             //Opening the door()
    10.  
    11.         }
    12.     }
    When an enemy is destroyed, they are classed as missing on the doors inspector. When all of the enemies are missing, I had hoped that == null would be called, but it is not.

    Could someone tell me what's wrong with the script?

    Thanks.
     
  2. BramVG

    BramVG

    Joined:
    Nov 15, 2015
    Posts:
    6
    The == is a comparison.
    Try changing: "isDone == true" to: "isDone = true".
     
  3. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Yes, one equals too many way used, however I this is a red herring. I will remove that from the below example. The bool of isDone is not relevant, enemy == null is never called.

    Code (CSharp):
    1. public GameObject[] enemy;
    2.  
    3. void Update ()
    4.     {
    5.         if(enemy == null)
    6.         {
    7.             openDoor();
    8.         }
    9.     }
    The enemy is within an array list, I feel this is why I am having problems. Once an enemy is destroyed, they are given a missing reference, how do I look for all of the references to be missing? If I could ask 'if (enemy == missing stuff', then it would be called.
     
  4. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    Yea first you should do isDone = true;
    2nd, if you destroy an enemy with Destroy() doesn't mean that the array will be null at the end. just the element in this array will be null.

    Code (CSharp):
    1. public GameObject[] enemy;
    2. public bool isDone= false;
    3.  
    4. void Update () {
    5.    if(CheckIfAllEnemyDead() && isDone == false) {
    6.       isDone = true;
    7.       //Opening the door()
    8.    }
    9. }
    10.  
    11. bool CheckIfAllEnemyDead() {
    12.    for ( int i = 0; i < array.Length; i++) {
    13.        if( enemy[i] != null) {
    14.          return false;
    15.       }
    16.    }
    17.    return true:
    18. }
    19.  
    maybe this will work
     
  5. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    The enemy array does not become null, just each slot in the array becomes null
    the array spaces to hold an enemy are still all there, so not null

    you need to check each array element
    Code (CSharp):
    1. bool allDead = true;
    2. for(int i = 0; i < enemy.Length; i++){
    3.   if(enemy[i] != null) {
    4.     allDead = false;
    5.     break;
    6.   }
    7. }
     
  6. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Hey, I just worked it out -

    Code (CSharp):
    1.     void Update ()
    2.     {
    3.         foreach(GameObject elem in enemies)
    4.         {
    5.             if(elem == null)
    6.             {
    7.                 openDoor();
    8.             }
    9.         }
    Thanks for the feedback, it is appreciated.
     
    MrMattyMoses likes this.
  7. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    your code will openDoor for every enemy which is dead

    and that multiple times per second
     
    kittik likes this.
  8. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Yeah, the code is -
    Code (CSharp):
    1. void Update ()
    2.     {
    3.         if(isDone == false)
    4.         {
    5.             foreach(GameObject elem in enemies)
    6.             {
    7.                 if(elem == null)
    8.                 {
    9.                     openDoor();
    10.                 }
    11.             }
    12.         }
    13.     }
    And under openDoor(), I change isDone to true.
     
  9. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    more like that yes. but also little hint, don't use foreach on runtime and updates, causes garbage. better is a for loop.

    Code (CSharp):
    1. for(int i = 0; i < enemies.Length; i++) {
    2.       if(enemies[i] == null) {
    3.          openDoor();
    4.       }
    5.  }
     
    kittik likes this.
  10. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Thanks @martinmr, I didn't know that using foreach in Update was a bad idea. I have used your code, but am finding that after each enemy is made null, openDoor() is called. Any idea why?

    Code (CSharp):
    1. void Update ()
    2.     {
    3.         if(isDone == false)
    4.         {
    5.             for(int i = 0; i < enemies.Length; i++)
    6.             {
    7.                 if(enemies[i] == null)
    8.                 {
    9.                     StartCoroutine(openDoor());
    10.                 }
    11.             }
    12.         }
    13.     }
     
  11. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    Try if (!enemy) instead of if (enemy == null)
     
    kittik likes this.
  12. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    @LaneFox, just tried it, but it called the function on the first enemy being destroyed. It's odd.

    Code (CSharp):
    1. void Update ()
    2.     {
    3.         if(isDone == false)
    4.         {
    5.             for(int i = 0; i < enemies.Length; i++)
    6.             {
    7.             if(!enemies[i])
    8.             {
    9.                 StartCoroutine(openDoor());
    10.             }
    11.             }
    12.         }
    13.     }
    Note, I kept the for(int i = etc.) as the console didn't accept enemies, enemies[]. The ! operator cannot be applied to operand of type ...GameObject[].

    I guess keeping for(int i = etc.) is likely the reason why this is not working.

    Code (CSharp):
    1.     void Update ()
    2.     {
    3.         if(isDone == false)
    4.         {
    5.             {
    6.             if(!enemies)
    7.             {
    8.                 StartCoroutine(openDoor());
    9.             }
    10.             }
    11.         }
    12.     }
    Does not work.

    Any ideas how to call !enemies when the ! operator cannot be used currently? Thanks.
     
  13. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    Code (CSharp):
    1. public GameObject[] enemy;
    2. public bool isDone= false;
    3. void Update () {
    4.    if(isDone == false && CheckIfAllEnemyDead()) {
    5.       isDone = true;
    6.       openDoor()
    7.    }
    8. }
    9. bool CheckIfAllEnemyDead() {
    10.    for ( int i = 0; i < array.Length; i++) {
    11.        if( enemy[i] != null) {
    12.          return false;
    13.       }
    14.    }
    15.    return true:
    16. }
    Checks if all enemys are dead, if just one is alive, it will return false so it even hasn't to go through the rest of the array. If all are dead -> null than it will reach the return true.

    @kittik yea you are right, my last code posted was opening every time enemy is dead. this should fix it.
     
    kittik likes this.
  14. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Thank you @martinmr, that code works as intended, appreciate the assistance.
     
  15. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    If I were to keep going with an approach like this I believe I would store my enemies in a List... when they die I'd remove them. Then just check if the List count > 0.
     
    martinmr likes this.