Search Unity

NullReferenceException when variable should not be null

Discussion in 'Scripting' started by TheHammer1, Feb 6, 2019.

  1. TheHammer1

    TheHammer1

    Joined:
    Oct 15, 2015
    Posts:
    20
    I'm creating a game with some shooting involved. I have a variable that contains information for weapons that is set whenever the player presses number keys. This variable dictates the values used when shooting. However, I get a NullReferenceException after a few shots, weird since it never changes the value to null in the shooting code. I've also added logic to prevent this, but it doesn't work. Any suggestions?

    Code (CSharp):
    1. if (Input.GetMouseButtonDown (0) && currentWep.Ammo > 1 && Time.time > nextFiringTime) { //shoots on click if ammo is greater than 1 and the firerate allows it
    2.             /// checks if variables are null before changing them
    3.             if (currentWep.FireRate != null)nextFiringTime = Time.time + currentWep.FireRate; /// used for the firing rate.
    4.             if (currentWep.Ammo != null) currentWep.Ammo--; // negates ammo on shot IF ammo is not null
    5.             if (currentWep.FireSound != null)playerSFX.PlayOneShot (currentWep.FireSound, 5f);
    6.             RaycastHit objHit; // the object the bullet has hit
    7.  
    8.             if (Physics.BoxCast (center:gunShooter.transform.position, halfExtents:currentWep.WepExtents, direction:gunShooter.transform.forward, hitInfo: out objHit, orientation:Quaternion.identity)) { ////Casts a Boxcast that is infinite in the Z and Y directions but not X directions. This reperesents a bullet. Similar to Doom shooting.
    9.  
    10.                 print (objHit.collider + " was hit.");
    11.                 AI_Behavior ai = objHit.collider.GetComponent<AI_Behavior> (); ///detects the AI script, which contians the ai's health
    12.                 if (ai) {
    13.                     ai.health -= currentWep.Damage; //negates health by damage
    14.                 }
    15.  
    16.             } else {
    17.                 print ("Nothing was hit."); //didnt get anything
    18.             }
    19.         }
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    4,665
    Which line does the error occur on?
     
  3. TheHammer1

    TheHammer1

    Joined:
    Oct 15, 2015
    Posts:
    20
    On the very first line. If currentWep.Ammo is commented out, the line occurs on 3. I'm not sure how the variable becomes null, only that it becomes null after clicking a few times.
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    4,665
    I'm not seeing anything in there for currentWep being set to null. So you'll just need to see where you might be setting it to null anywhere else?

    In Visual Studios, if you right click on currentWep and choose "Find all references" you should at least see all the locations in script that reference the variable and maybe you'll see something from another script possibly.
     
  5. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    635
    It isn't the variables which are null. it is the reference to the currentWep class.

    Where do you set and remove that reference?
     
  6. TheHammer1

    TheHammer1

    Joined:
    Oct 15, 2015
    Posts:
    20
    currentWep is assigned to on Start(). You cannot fire the weapon until you select a weapon (by pressing a number). If you fire a selected weapon, it will work until after a few shots.

    Assigning currentWep in Update() will stop the error but the player cannot select weapons anymore (which I don't want).
     
  7. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    116
    not alot we can do without seeing the full script, since that snippet looks right
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,088
    OK, that strongly suggests that the problem is that currentWep had a value of null. So something, somewhere, is setting currentWep to null. It sounds like that's not supposed to happen, so you have a bug somewhere.

    But you should also consider writing some "defensive" code here to check for that case. I'd probably change this line:

    if (Input.GetMouseButtonDown (0) && currentWep.Ammo > 1 && Time.time > nextFiringTime) {


    ...to something like this:

    if (currentWep != null && Input.GetMouseButtonDown (0) && currentWep.Ammo > 1 && Time.time > nextFiringTime) {


    That will stop you from trying to shoot a null weapon. You'll still want to fix whatever was causing the weapon to become null in the first place, but this should prevent an exception in case something goes wrong.
     
    Last edited: Feb 21, 2019
  9. drcrck

    drcrck

    Joined:
    May 23, 2017
    Posts:
    279
    NullReferenceException also occurs when you try to do anything with a destroyed object, even if the reference variable is not null

    btw do you really need a comment that explains how the -= operator works? :D
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,517
    One thing you can do when this is the case, if it's in code you control, is to make the variable a property that outputs a log line anytime it's changed. When it's set to null, you can not only get a log of when it happens, but a full stacktrace that will more often than not point to exactly where the problem is.
    Code (csharp):
    1.  //before
    2.  
    3. public SomeClass currentWep;
    4.  
    5. //after
    6. public SomeClass currentWep {
    7. get {
    8. return _currentWep;
    9. }
    10. set {
    11. if (value == null) {
    12. Debug.Log("Setting to null here! Check the stacktrace.");
    13. }
    14. _currentWep = value;
    15. }
    16. private SomeClass currentWep;
    17.