I am writing a property drawer that needs to be notified when just before the serialization pass and just after the deserialization pass. Unsurprisingly, inheriting from ISerializationCallbackReceiver in the property drawer does not seem to get this functionality.
Is there a way to get similar events for the property drawer?
I know that the SerializeField attribute probably uses some sort of internal workaround that is not available to us, but I am looking for very similar functionality.
I have largely used property drawers to make my classes less dependent on their containing class so that they can be used without needing to do a whole bunch of setup. Being able to control serialization at the property drawer level takes this up a notch. Currently I have a property drawer that handles serialization and deserialization through buttons that show in the inspector. This means that you have to keep track in your head of when unity saves and loads data, instead of unity just notifying you.
Basically, I want to set it up so some non-MonoBehaviour classes so that they know how to serialize their own data when used inside a MonoBehaviour.
So PropertyDrawer’s don’t exist unless the inspector is showing. So it won’t necessarily receive the event as it’s not necessarily instantiated at that moment.
SerializeField is just an attribute. When serialization occurs, Unity just reflects all the fields off an object. And it serializes it if:
Is a serializable type
Is public OR marked with the SerializeFieldAttribute.
I don’t know off the top of my head of any hook into the serialization event outside of ISerializationCallbackReceiver. You could of course create your own static event on the types that you’re creating, then fire them in the ISerializationCallbackReceiver. BUT this means that you have to boiler plate this code for each and every type, and also means that there’s the added overhead of all of these types having this interface on it that you’d likely want to remove on build… you of course could use the compiler symbols to do that… but then what of the types that need it at runtime too.
I don’t know… just spit-balling. I’m not fully understanding what it is you’re attempting to accomplish though. What would you be doing with these PropertyDrawer’s that can receive this event anyways? Is it so you can create attributes for fields that control how they serialize to other fields? Like maybe you have a Dictionary, and an array of KeyValuePair, and you attribute the Dictionary pointing it at the KeyValuePair array, and the PropertyDrawer knows to ToArray the dict into the array field?
Cause I mean… if that’s what you want… well a big issue I see is that the PropertyDrawer won’t exist at runtime and therefore the deserialization logic won’t exist since it’s in the editor code.
I could think maybe implementing a mixin system that could work this way… but again, I’m work on assumption/speculation at this point since I don’t know your design/goal.
ISerializationCallbackReceiver should be in the class you are setting up the property drawer for. The serialization system will call OnBeforeSerialize() and OnAfterDeserialize() on the objects it is serializing/deserializing that inherit that interface.
What exactly are you doing that you would need this in the property drawer?
I have lots of uses of it, but my current usage is an abstract list. Each item knows how to save and load itself both in and out of a list. Like I said, I have two buttons I can press that serialize it into a format unity can handle, and those are displayed in a property drawer. I would, however, like the property drawer to know when to save and load on its own.
The list is only edited in the inspector when you have it selected in the inspector. The rest of the time it just assumes that it will need to load itself to from the serialized data.
As stated, manually clicking on the buttons I have exposed in the property drawer works, it just requires you keep in your head what the serialization state of the object is instead of unity managing it for you.
I was hoping that serialized properties would be notified in some way when they are getting serialized or deserialized and that I could hook into that in some fashion. This would reduce developer error since they can trust that it is saving their actions like any other field would.
Do OnBeforeSerialize() and OnAfterDeserialize() get called on classes that are not MonoBehaviours? I am trying not to have the class require its parent to make changes to support it.