Is there a reason not to inherit from UnityEngine.Object if I wanted the basic functionalities that UE.Object gives?

I was writing an editor to one of my objects - the object has a list of TextEntry (TextEntry is a System.Object) - I usually start my classes out as regular C# classes, and then if at one point I notice that they need to live in the scene, or need to have an update method, etc. I make them MonoBehaviours.

The problem with dealing with System.Objects in editors, is that they don’t cope too well with SerializedProperties - if you have a SP that points to a System.Object, you can’t get the correct object reference value - since SP.objectReferenceValue returns a UE.Object and AFAIK there’s no correct conversion between UE.Object and System.Object (please correct me if I’m wrong)

So I thought oh well, in this case I just want my objects to work well with SerializedProperties, I don’t want them to act as MonoBehaviours and there’s no need for them to be ScriptableObjects too - so why not just inherit UE.Object in this case?

I’ve never seen anyone do it - Is there a reason not to?

Thanks for any help.


Well, it seems that I can’t even instantiate a UE.Object successfully!


var o = new Object(); // o is null after that...


public class MyObject : Object { }
var mo = new MyObject(); // same

Yes there are reasons :wink: UnityEngine.Object is the base class of all built-in Unity objects. It usually has a respective counterpart in the native part of the engine. The only two (runtime) classes you should use as baseclasses are “MonoBehaviour” and “ScriptableObject”.

As you might know the scripting “engine” in Unity is Mono. Mono runs is a managed environment. It’s actually impossible to destroy / delete an object instance. It’s always the garbage collector which frees the memory. However we all know the Destroy method, so how does this fit? Well as i said above most objects have a native-code part and a managed part. Since we work in the managed environment we only see / can work with the managed part. Whenever you use Destroy on such an object you actually just destroy the native part of that object. The managed part is garbage collected once there are no references to the object anymore.

Unity used a hacky “trick” to make the managed part “pretend” to be null when the native part is destroyed. That’s why your created “Object” seems to be null. This behaviour makes it impossible to derive your own classes directly from UnityEngine.Object. A MonoBehaviour has a native part (that’s also the part where the events like Update, Start … comes from)

UnityEngine.Object by itself only have the instanceID on the managed side. Everything else, even the “name” and “hideFlags”, are implemented external, on the native code side. So without creating a proper object which has both, a managed and native side, a UnityEngine.Object is useless.

If you want a class to be serializable by unity it has to be derived from MonoBehaviour or ScriptableObject, there’s no way around that. In most cases it’s easier to just use MonoBehaviours especially if you need the class to be serialized in the editor. ScriptableObjects need to be serialized “on their own” as asset.