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??
IEnumerator DestroyRandomStuff(Collision2D collision) {
yield return new WaitForSeconds(0.5f);
if(collision?.gameObject?.GetComponent<DestroyMe>() != null) { // This is line 438 referenced in error below
collision.gameObject.GetComponent<DestroyMe>().DestroyThis();
ChangeSpeed(baseSpeed);
}
}
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+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?
The ? operator do not work with unity objects because they have comparsion operator overloaded for their own purpose
Inside the Collision2D.gameObject getter function there’s following code:
/// <summary>
/// <para>The incoming GameObject involved in the collision.</para>
/// </summary>
public GameObject gameObject
{
get
{
return !((Object) this.rigidbody != (Object) null) ? this.collider.gameObject : this.rigidbody.gameObject;
}
}
It looks wrong. It looks like the object you’re colliding with have a collider, but no rigibody?
@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.
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.
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() 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.
@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.
IEnumerator DestroyRandomStuff(DestroyMe destroyMe) {
yield return new WaitForSeconds(0.5f);
if(destroyMe != null) {
destroyMe.DestroyThis();
ChangeSpeed(baseSpeed);
}
}