How do you understand SerializedObject and SerializedProperty? What are they and why should we use them?
SerializedObject and SerializedProperty allow you to programmatically change elements in your MonoBehavior at design time while still allowing the Unity Editor to recognize the changes and serialize them for you. There are some other excellent uses of this… for instance, you can use this in OnValidate() to update multiple properties based on changing something within the editor. An example might be if you change a character’s level in the editor, you can use this system to automatically adjust the character’s hit points or attack values…
There is a downside to this approach, however, or at least a cautionary tale. In order to use this method of editing properties, you need to be using Unity.Editor. The catch is that the finished build can contain no code that uses anything from the Unity.Editor namespace, it’s automatically stripped out of your code. Unmodified, the code in Sam’s example simply will not build when you go to Build and Run. It will only run within the editor. When you build, you’ll get a message that SerializedObject does not exist in the current context, and the build will fail…
Don’t panic.
Simply add a few lines of code and you’ll be good to go…
#if UNITY_EDITOR
using Unity.Editor;
#endif
Then surround the entire Update() method with the same #if UNITY_EDITOR #endif tags. The editor will then remove these bits of code when it goes to build and all will be good.
Couldn’t have put it better myself!
I will be covering this in the wrap up.
after re-going over parts of this video and reading the unity docs:
I still don’t fully understand what the SerilizedObject and property are doing.
Is this used to make a monobehaviour class that usually isn’t serializable, serializable?
And then the property is to access the field from that class in a serialized form?
However since it is in a serialized form that’s why there is no datatype safety and we have to manually make sure we look for the correct datatype from the property?
@Brian_Trotter mentions
SerializedObject and SerializedProperty allow you to programmatically change elements in your MonoBehavior at design time while still allowing the Unity Editor to recognize the changes and serialize them for you.
What about this specifically makes it so the unity editor recognizes these changes as the only way to serialize a monobehaviour or is this one way that also does something unique for the unity editor?
I know I’m asking a lot of questions but this is the one concept so far I’m really struggling to understand.
A lot of this is under the hood handwavy magic stuff that ordinarily we never actually see. It comes into play when we write Editor code, which OnBeforeSerialize happens to be.
Suppose you have a custom editor to edit an absurdly silly class:
public class Foo : Monobehaviour
{
[SerializeField] private float bar;
}
In our Editor code, the SerializedObject is the instance (what we’ve attached to the GameObject) of Foo.
The SerializedProperty is the specific field in the instance of the Foo class “bar”.
The reason that there is no datatype safety is because SerializedObjects and SerializedProperties are very generic classes, and not in the List<T>
type of generic way. All SerializedObjects and SerializedProperties are actually saved in the file system as strings… So a string value might be 0 or 42 or 867.5309 or a very long string of characters representing a reference into the file system. It’s up to the Editor code to know exactly what that type is and get the correct value from the property. The straight editor code does this very well. Custom code (the stuff we write, like what we did in OnBeforeSerialize) needs to know exactly what type the field is supposed to contain.
Implementing “uniqueIdentifier” is complicated.
“public string uniqueIdentifier => transform.GetInstanceID().ToString();” would that work?
No, it wouldn’t, because between sessions any given object may have a different InstanceID. There is no guarantee that the same component will have the same ID when you reload it.
Actually, for some issue I had about switching between the scenes when I added saving the states (in the Save-System as an asset section) I added log messages for the InstanceID
s and one could clearly see that they’re pretty much what the name says, the ID of a particualar instance of some gameObject, so every time the game switches between scenes all objects that are serialized in the scene file are instantiated and thus get all new instance IDs.
(They’re pretty much similar to what a “PID” (or "process ID) is on a Unix or Linux system. Each time you run a command a new process instance of it is spawned and gets a fresh PID…)