2
\$\begingroup\$

In the OnTriggerEnter2D function of my Bullet script, I have the following code:

private void OnTriggerEnter2D(Collider2D other)
{
     if (other.CompareTag("Enemy"))
     {
         var enemy = other.GetComponent<Enemy>();
         enemy?.Death();
     }
}

The reason for the null conditional operator (the question mark) in enemy?.Death() is because the Death function actually destroys the Enemy component script, so it suppresses an error when the bullet hits the enemy again. It's supposed to be shorthand for:

if (enemy != null)
    enemy.Death();

The code works; the error is suppressed. However, the IDE that I'm using, Jetbeans Rider, gives the following warning:

'?.' on a type deriving from 'UnityEngine.Object' bypasses the lifetime check on the underlying Unity object.

What does that mean exactly? Should I continue using the null conditional operator?

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

That is because Unity overrides the == operator (and therefore !=), changing its behavior, and the ?. operator does not use their version.

For more information, see Custom == operator, should we keep it?.

To summarize: Unity objects are wrappers around a C/C++ object. When that object is Destroy()ed, the underlying C++ object is also destroyed but the C# object has to wait until it is garbage collected.

That also means that you should not compare to null, and instead do:

var enemy = other.GetComponent<Enemy>();
if (enemy)
    enemy.Death();

Another reference: Don't Use == null On Unity Objects

\$\endgroup\$
2
  • \$\begingroup\$ So as I understand it, calling Destroy(Enemy); destroys the native c++ object, and the null conditional operator will check for that, so why should I care that the actual c# object is not destroyed? \$\endgroup\$
    – Sean Carey
    Commented Mar 22, 2020 at 0:41
  • 2
    \$\begingroup\$ The problem is that the null conditional operator will not check for that, as the warning describes ("bypasses the lifetime check"). It checks whether the C# object is null, which in general it might not be, even if it's been destroyed. So you might try to double-destroy an already-destroyed component. In your specific case you're probably safe - GetComponent should return a real null if there's no non-destroyed component of that type. But the IDE doesn't know that, so it warns you about a potential error you could run into with this construct, say if using a cached reference. \$\endgroup\$
    – DMGregory
    Commented Mar 22, 2020 at 3:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .