Search Unity

(SOLVED) nullreference in if statement

Discussion in 'Scripting' started by munkbusiness, Mar 20, 2019.

  1. munkbusiness

    munkbusiness

    Joined:
    Aug 22, 2017
    Posts:
    46
    EDIT: SOLVED
    Solution in comments. Keeping the post as is, for future googlers.

    Hey I have been strugling with this for a little while now. I have a coroutine that destroys an object, but I also have other code that can destroy the object, so to check if it still exist I do a null check, but I somehow get my null reference error in the null check itself??

    Code (CSharp):
    1. IEnumerator DestroyRandomStuff(Collision2D collision) {
    2.         yield return new WaitForSeconds(0.5f);
    3.         if(collision?.gameObject?.GetComponent<DestroyMe>() != null) { // This is line 438 referenced in error below
    4.             collision.gameObject.GetComponent<DestroyMe>().DestroyThis();
    5.             ChangeSpeed(baseSpeed);
    6.         }
    7.     }
    Also tried this check which in theory is the same, and I get the same error:
    if(collision != null && collision.gameObject != null && collision.gameObject.GetComponent<DestroyMe>() != null)


    Error:
    NullReferenceException: Object reference not set to an instance of an object
    UnityEngine.Collision2D.get_gameObject () (at C:/buildslave/unity/build/Modules/Physics2D/ScriptBindings/Physics2D.bindings.cs:2334)
    DestroyPlatform+<DestroyRandomStuff>d__28.MoveNext () (at Assets/Scripts/Machines/DestroyPlatform.cs:438)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)

    I am really lost as to why this happens, something todo with Coroutines?
     
    Last edited: Mar 21, 2019
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,296
    The ? operator do not work with unity objects because they have comparsion operator overloaded for their own purpose
     
  3. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,296
    Inside the Collision2D.gameObject getter function there's following code:
    Code (CSharp):
    1.     /// <summary>
    2.     ///   <para>The incoming GameObject involved in the collision.</para>
    3.     /// </summary>
    4.     public GameObject gameObject
    5.     {
    6.       get
    7.       {
    8.         return !((Object) this.rigidbody != (Object) null) ? this.collider.gameObject : this.rigidbody.gameObject;
    9.       }
    10.     }
    It looks wrong. It looks like the object you're colliding with have a collider, but no rigibody?
     
  4. munkbusiness

    munkbusiness

    Joined:
    Aug 22, 2017
    Posts:
    46
    @palex-nx Yeah I was unsure about the ? operator, which is why I tried the old solution also as mentioned in op.

    I checked my objects for rigidbodies, both objects involved in the collision has a rigidbody. IDK if it matters, but the object with destroyme-script on it is a child of another object that also has a rigidbody.
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,543
    First, separate your "old solution" out into 3 separate if statements so you can figure out exactly what is null. I wouldn't bother thinking about all the what ifs here until you do that.
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,258
    Based on the error message, the exception is occuring inside the getter for the collision.gameObject property. So it's not that collision is null, and it's not that collision.gameObject is null, it's that the code that implicitly executes when you ask it to calculate collision.gameObject is, itself, throwing an error. That suggests to me that your collision object is not null, but is somehow corrupt.

    This is a shot in the dark, but I would try calculating collision.gameObject.GetComponent<DestroyMe>() before your coroutine waits and saving it in a local variable. That way, if the collision object is somehow getting corrupted during the wait, it won't affect you.
     
  7. munkbusiness

    munkbusiness

    Joined:
    Aug 22, 2017
    Posts:
    46
    @Antistone I tried your solution and I am rid of the error and it runs like I would expect, thanks a lot. So I basically find DestroyMe and submit that into the IEnumerator.

    Code (CSharp):
    1. IEnumerator DestroyRandomStuff(DestroyMe destroyMe) {
    2.         yield return new WaitForSeconds(0.5f);
    3.         if(destroyMe != null) {
    4.             destroyMe.DestroyThis();
    5.             ChangeSpeed(baseSpeed);
    6.         }
    7.     }