Note sure, but it could be how the null coalescing operator works under the hood.
UnityEngine.Object instances have the Equals and GetHashCode functions overriden and will throw null when in fact they exist(after they are marked for destruction). Depending on how the null coalescing operator works (something I’ve not seen before, and looks pretty handy), it could be using a different equality comparison, or comparison to null than the special version used for Components. It’s possible that there is some under the hood trickery that is tricking that operator. You could try creating the necessary comparison functions for you components to see if it changes anything.
Your first sentence explains it I think. When you say “if (something)” I believe it is just syntatic sugar for if (something==null) when something cannot be cast to boolean and is a nullable type. So if Objects override Equals then they probably will return a null when compared with == even though they are not null according to the ?? operator, which must not use the classes overrides.
That does get the code all in one line, but it’s slightly slower than my method because you are calling GetComponent<> twice if the rigidbody already exists. I realize the difference is probably trivial in most cases unless you are accessing a lot of rigidbodies.
The null-coalesce operator is handy because you can chain together a whole bunch of things…
I dunno, if I had to do a = b ?? c ?? d ?? e ?? “f”;
I think I would feel that I did something wrong in the design phase.
You can embed multiple ternary operators(even though it is damn near impossible to read):
int a = 5;
int b = a < 1 ? a < 2 ? a < 3 ? 4 : 5 : a < 6 ? 7 : 8 : 4;
But I place it in the same situation of I felt I did something wrong in implementation to need that sort of behaviour.
Missing Component Exception is a Unity Specific exception that does relate to the Equals Override, so it’s likely a ReferenceEquals(object, null); sort of comparison that cannot be overridden.
using UnityEngine;
public static class GameObjectExtensions
{
public static T GetComponent<T>(this GameObject gameObject, bool add) where T : Component
{
var value = gameObject.GetComponent<T>();
if (value == null && add)
value = gameObject.AddComponent<T>();
return value;
}
public static T GetComponent<T>(this Component component, bool add) where T : Component
{
return component.gameObject.GetComponent<T>(add);
}
}