Search Unity

If statement check for null not working

Discussion in 'Scripting' started by GD-Darren, Jul 3, 2013.

  1. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    I have this piece of code here:
    Code (csharp):
    1.  
    2. // Check if player equipped something
    3.             if (equipment != null)
    4.             {
    5.                 InstantiateEquipment(equipPosObj, equipment);
    6.             }
    7.  
    The equipment instantiating works perfectly, however there's a problem. When the equipment variable is set to null, it still manages to go through the if statement while being null and unity throws a runtime ArgumentException: The thing you want to instantiate is null.

    I don;t get this and I'm out of ideas, because the if statement shouldn't let the equipment try to instantiate if it's null.

    Thanks in advance.
     
  2. XGundam05

    XGundam05

    Joined:
    Mar 29, 2012
    Posts:
    473
    What is the relation of equipPosObj to the equipment object?

    Because what is occurring is that equipment is not null but equipPosObj is.
     
  3. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    equipPosObj is set as reference in the editor so it's never null.

    EDIT: More info

    Here's the method InstantiatePrefab

    Code (csharp):
    1.  
    2. // Instantiates an equipment prefab
    3.     void InstantiateEquipment(Transform equipPosObj, Equipment equipment)
    4.     {
    5.         if (equipment!= null)
    6.         {
    7.             GameObject prefab = (GameObject)Resources.Load("Equipment/" + equipment.name);
    8.                         GameObject instantiatedPrefab = (GameObject)GameObject.Instantiate(prefab); // ERROR THROWN HERE BECAUSE prefab wasn't loaded since the equipment is null
    9.             instantiatedPrefab.transform.parent = equipPosObj;
    10.                  }
    11.         }
    12.  
    I'm sure the Resource.Load is working because if I set the equipment manually before runtime it loads the prefab, however when the equipment is null it throws an exeption. The error has to do with the equipment != null checking I'm sure.

    Equipment is also a class I created manually with some variables like name, description etc, maybe is that the reason != null is not catching it?

    Any possible solutions to this would help me greatly, thanks again.
     
    Last edited: Jul 3, 2013
  4. XGundam05

    XGundam05

    Joined:
    Mar 29, 2012
    Posts:
    473
    Sorry, had a brain fart when looking at your code -.- (thought I was looking at a different function call -.-). What is the code in InstantiateEquipment?
     
  5. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    Code in edit.
     
  6. Eiznek

    Eiznek

    Joined:
    Jun 9, 2011
    Posts:
    374
    If you set Equipment to a new Object such as

    Code (csharp):
    1.  
    2.  Equipment e = new Equipment();
    3.  
    In another part of the code. Then the Equipment variable will never return null because it is a new variable. Maybe it has no information.. but its still not null.

    You could make a boolean in equipment called isSet = true and use that instead.. Or check if the equipment is a new object..

    Code (csharp):
    1.  
    2.  if (!equipment.equals(new Equipment()))
    3.  {
    4.  }
    5.  
     
  7. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    Thanks Eiznek I'm thinking of using that, however what I'm currently doing is

    Code (csharp):
    1.  
    2. Equipment e = null;
    3.  
    at the start, than I check my database and if an equipment is found I set the equipment to the found equipment.

    Now if the equipment is found, it works and loads the equipment, however if no equipment is found in the database and e remains null, shouldn't the if statement catch that e is null since I specifically set it to null at the start and it was never changed?

    Thanks in advance
     
  8. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    If equipment is a class and not a struct, this will return falls as it does it's equality check based on Reference (i.e. the objects being compared are actually the same object in memory). Also, doing this check will instantiate and immediately mark for garbage collection a new Equipment object if it's a reference type (class) so this would be very bad... it would create lots of unnecessary garbage collections.
     
  9. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    Sorry Dustin but checking if it's null and entering if it is null doesn't make any sense, I only want to instantiate an object that is not null.

    Right now I am going to try a modified Eiznek method where I instantiate a new Equipment for equipment that aren't used and do the checking by checking if the name is empty or set. If the name is empty it would mean that the equipment is not set. Hopefully this works, will keep you updated.
     
  10. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Oh nevermind... I'm an idiot. :) I didn't read carefully enough. I thought you were setting the equipment variable if it was null, but it's a prefab that you're instantiating.
     
  11. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Try this:

    Code (csharp):
    1.  
    2. if(!UnityEngine.ReferenceEquals(equipment, null))
    3. ...
    4.  
    My guess is that the equipment object has been marked for destroy/disposal but the reference itself isn't actually null... try using the UnityEngine ReferenceEquals method to see what it comes back with...
     
  12. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    My guess is your path to the resource is bad and Resources.Load is returning null. This makes prefab null which throws an exception when you try to instantiate it.

    Further to the point - if what you really need is the name member of Equipment and you're only providing a parameterless constructor then what you should really be checking is if name is not null and also not equal to string.Empty.
     
    Last edited: Jul 3, 2013
  13. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Code (csharp):
    1.  
    2.     if(!UnityEngine.ReferenceEquals(equipment, null)  !string.IsNullOrWhitespace(equipment.name))
    3.  
     
  14. GD-Darren

    GD-Darren

    Joined:
    Jan 12, 2013
    Posts:
    53
    Thank you everyone, I finally got a fix thanks to you all who suggested ideas.

    What i did was to add a method to the class equipment

    Code (csharp):
    1.  
    2.     public bool IsNull()
    3.     {
    4.         return string.IsNullOrEmpty(name);
    5.     }
    6.  
    where it checks the name of the equipment and if its null or empty returns null. This works flawlessly and hopefulyl can help people with the similar issue in the future.
     
  15. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Good deal. :) Realized my script should have been UnityEngine.Object.ReferenceEquals anyway.
     
  16. 1sd15

    1sd15

    Joined:
    Dec 15, 2015
    Posts:
    16
    Well, this is probably quite a late reply, just found this now. So, I had the exact same problem and I knew that it couldn't be that the object was not null, as I set a new private GameObject to null which had never been anything else before.

    Long story short, after a while of searching, I found people using "== null" and I had a look at your code, which looked the same as mine, then looked at some other pieces of code and had an aha moment. It uses bool I think and we both should have used double equals rather than just one, easy little pitfall.

    So, the solution that appeared to work for me was using "==" rather then "=", case closed.