Serialization In Depth
Tim Cooper @stramit
Who Am I?
Developer at Unity Used to make games!
Bioshock 1 / 2
Responsible for:
Editor features Graphics features
Topics
Overview How serialization works How to serialize
Classes Class References ScriptableObject Arrays
Topics
Working with Assets
Creating an asset Custom GUI for assets Using an asset at runtime Sub-assets
Overview
Why write nicely serializable classes?
Editor windows will survive assembly reload Ability to save data as custom asset les Easier than writing your own Once you know how it works ;)
Overview
When does serialization happen?
On assembly reload Script recompilation Enter / exit play mode Loading and saving the project / scene
How serialization works
Assembly reload
Pull all data out of managed (mono) land Create internal representation of the data on C++ side Destroy all memory / information in managed land Reload assemblies Reserialize the data from c++ into managed
If your data does not make it into c++ it will go away!
Serializing Classes
A simple class will not automatically serialize! Unity does not know if the class is meant to serialize or not!
We can x this!
Serializing Classes
A class needs to be marked up to serialize
[Serializable]
Field serialization rules
public - always serialize private / protected - serialize on assembly reload (editor) static - never serialize
Serializing Classes
Field serialization modiers
[SerializeField] - Make private / protected elds serialize [NonSerialized] - Never serialize the eld
Serializing Structs
User structs dont serialize
A few built in ones do
Dont use them for serialization!
Serializing Class References
Normal class references
Each reference serialized individually When you deserialize... you have different members Think of them as behaving like structs!
Use them when you have:
Data that is references only once Nested data
Serializing ScriptableObject
Serialize as reference properly!
Multiple references to this object Will resolve properly on deserialization
Supports some Unity callbacks
OnEnable, OnDisable, OnDestroy Create them with CreateInstance <type> ()
Serializing ScriptableObject
Use them when you want data
That is referenced multiple times Shared data Needs Unity system callbacks
Serializing ScriptableObject
Initialization order
Instance created Fields deserialized into object If they exist on the c++ side ;) OnEnable() Called
Serializing ScriptableObject
To create elds properly inside a SO
Dont create them in constructor Check if they are null in OnEnable () If not null... then they were deserialized if null... create them!
Hideags
Control visibility
Important if you are NOT saving the asset or holding a reference to it i.e editor only data structure referenced by a window
HideAndDontSave
No asset / scene root - tells unity to consider this a root object Will not get cleaned up on scene load (play mode) Destroy using Destroy ()
Serializing Concrete Arrays
Works as expected
No object sheering Serialized and deserialized properly
More complex objects?
Serializing Base Class Arrays
Does not work as expected
Breaks on deserialization Object shearing occurs
How can we serialize more complex hierarchies?
Serializing General Array
ScriptableObject Array!
Serializes as references... Will serialize as expected Only need to set hideags on the most root object
Asset Creation
Design the class you want to be an asset
Database, Character Info, ect
Ensure that the root is a ScriptableObject
An asset le is a ScriptableObject
Create the asset by calling
AssetDatabase.CreateAsset (object, location.asset) If is mandatory to use the .asset le extension
Custom Asset UI
Your asset is just like a Unity asset!
You can write custom editors [CustomEditor (typeof (YourType))] Extend from the EditorClass Remember to put in in an editor folder!
Property Fields
Delegate drawing to a separate class
Useful for custom controls
Can be implicitly linked to a class
[CustomPropertyDrawer (typeof (MyType))] Does not need to be marked up per eld
Can be hooked up via an attribute
Marked on a per eld basis!
Property Fields
How?
[CustomPropertyDrawer (typeof (MyType))] Extend PropertyDrawer Need a custom height? Override GetPropertyHeight () Do your custom drawing OnGUI ()
Using Assets
Create a reference to the type
Can be anywhere: EditorWindow MonoBehaviour
Connect it to an asset
Via code or the inspector
Do game specic things!
Using Sub-Assets
ScriptableObjects
Save each manually... they wont serialize to le all the way down
How?
Add them as children of another asset (AddObjectToAsset) By default it will show all assets as sub assets Set HideFlags to HideFlags.HideInHierarchy Much nicer :)
Using Sub-Assets
Use SubAssets for complex data structures
Where many elements are ScriptableObjects Graphs Databases ect!