Hey,
I’ve been working on a project where I needed Editor serialization. Therefore I opted to inherit most classes from ScriptableObject. As always I started off with the Editor console warnings suppressed. I’ve been using custom constructors with my classes for months now, without any issues, but I just noticed that I’ve been getting a new warning each time I use my constructors :
where TYPE is the type that inherits form ScriptableObject.
This is confusing. As I mentioned, I had absolutely no problems doing it this way, the only thing that made me notice the warnings was the framerate due to the ridiculous amount of console warnings.
Is this warning deprecated? Has anyone encountered cases where the extra CreateInstance function did anything useful? Can I just suppress it via pragma and forget about it alltogether?
Edit : Just realized it can’t be suppressed since it doesn’t have an ID…
The point of scriptable objects is mostly so you can serialize data in the editor. As far as I’m aware, you don’t want to be using constructors because that is likely to get in the way when Unity should be serializing the data.
The way to create ScriptableObjects is by using CreateInstance. Internally, Unity invokes the constructor for these types, but it may do so multiple times, or in whatever way it likes to.
You should always create new instances of ScriptableObjects using CreateInstance.
BTW: ScriptableObjects are used for more than just “editor serialization”… actually most people use them at runtime to store different values.
They don’t need to be scriptable objects at that point though. You can use any kind of class if you just want to store data at runtime or in an xml/json/binary file for persistence. What makes scriptable objects special is that the editor knows how to handle them, and outside of that use case, they aren’t particularly valuable.
This is (no longer?) always the case. In my case it doesn’t interfere at all.
That would be the parameterless constructor wouldn’t it ? I think that explains the warning then. All other constructors call the parameterless constructor afterall, and that one should never be overwritten or else it will mess with the serialization. So Unity put in a warning in the parameterless ScriptableObject constructor to remind us to never use, and in extension to never overwrite the parameterless constructor. (constructors can’t be sealed)
It’s just a pity we can’t suppress the warning because creating and using overloaded constructors is no problem at all.
Its called the factory pattern. The class owns a static method that is intended to be used instead of a constructor. You can probably do some google searches on why this pattern exists. Its a good chance the general reasons for the pattern are the same as why Unity choose to use it.
The most likely reason I can think of is that the ScriptableObject constructor does something special. And Unity devs didn’t want to rely on users calling the base constructor inside the inherited classes constructor.
Are you sure? Seems relatively pointless to me. At runtime you can just create a regular class. The main draw of ScriptableObjects is their persistence and their editor friendliness.
Let me rephrase: what was written above was that “The point of scriptable objects is mostly so you can serialize data in the editor”. This implies that you can use them only for saving things that you’re working on in the editor (and will not be used at runtime).
I meant that the data you’re serializing can also be used at runtime.
ScriptableObjects are nicer than just using plain serializable classes or any other data serialization format, in that indeed the editor plays nicely with them - you automatically get an inspector for them once they’re saved as assets in the project, and you can drag/drop other objects into their public fields.
I think the most important part about ScriptableObjects is that they retain their type after deserialization (Unity’s built in serialization is broken for polymorphism of custom classes - you end up with an instance of the base type).
You shouldn’t blindly inherit everything from scriptable objects.
You also shouldn’t ever blindly do anything while programming.
If you need serialization, it will work on plain classes just fine. (mark classes as System.Serializable)
The point of scriptable object is that multiple objects can reference one scriptable object instance AND those references will be correctly serialized (if you do that with plain classes, you’ll get duplicates on deseralization). The references can be assigned by drag and drop.
Most of the time, you don’t need that kind of thing.
I mostly use scriptable objects for configuration “files” that can sit within project and can be quickly referenced from elsewhere. They’re pretty much only useful as configuration files - you can achieve the rest of functionality using GameObjects, Transforms and by referencing individual components.
Both CreateInstance and constructor make calls to the native side, the only difference is that constructor first creates managed instance and then passes it to the native side for processing.
Both make call to the same native method, but different overload.
From the c# source you posted, this seems to be just an assumption. You don’t know what else these methods do on the native side if you don’t own the source code. And i suspect them to not do the same thing, but internally need to be called in order, but that’s also just an assumption.