Looked up
Script serialization
Http://docs.unity3d.com/Manual/script-Serialization.html
Custom serialization and Examples:
Http://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.OnBeforeSerialize.html
and unity Holy Scriptures
On the basis of this Bo friends and then summarize the unity of the serialization
The purpose of serialization is to display variables (classes, structs, and so on) on Inspector (the Inspector panel).
when Unity has been serialized at runtime when it can see variables (classes, structures, etc.) on the Inspector (view panel);
Unity's serialized keywords are Serializable and Serializefield.
Serializable: Used for custom, non-abstract classes. Structure, so that this type can also be serialized
Serializefield: For non-public types (such as private), so that non-public types can also serialize
What conditions do the fields of a script need to be able to be serialized? (Must be met at the same time)
1. Public type, or [Serializefield]
2. Not static
3. Not const
4. Not readonly
5. Type must be a type that Unity can serialize
What type of Unity can be serialized?
1. Custom, non-abstract class, with [Serializable]
2. Structure with [Serializable]
3. References to Unityengine.object subclasses
4. Native type (int,float,double,bool,string, etc)
5. Arrays of the above types
6. The above types of list<t>
In the following cases, the serialization of unity does not necessarily perform as you would expect:Custom class image structure: to be understood
[Serializable] class animal{ publicstring name; class myscript:monobehaviour{ public animal[] animals;}
Variable with NULL in the class member:
For example, when serializing a variable (class. struct, etc.), if there is null,unity in the variable that will instantiate a new object, then serialize, and then go to the dead loop, because Unity's serialization runs on a non-main thread, this situation can cause program performance to degrade
class test:monobehaviour{ public trouble t;} [Serializable] class trouble{ public trouble T1; Public trouble T2; Public trouble T3;}
Polymorphism not supported: to be understood
If we want to correctly serialize the above problem, we need to use the Iserializationcallbackreceiver interface:
Onbeforeserialize ():
This method is run before unity serialization to inform you that unity will be ready to serialize
Onafterdeserialize ():
This method is run after unity serialization to inform you that unity will have been serialized out
For example, I want to create a serialization tree type class that has null variables, violates the second limit, and allows unity to run the serialization directly, which will result in large tree type data and performance degradation.
usingUnityengine;usingSystem.Collections.Generic;usingSystem; Public classveryslowbehaviourdonotdothis:monobehaviour{[Serializable] Public classNode { Public stringInterestingvalue ="value"; //The field below is what makes the serialization data become huge because//it introduces a ' class cycle '. Publiclist<node> children =NewList<node>(); } //This gets serialized PublicNode root =NewNode (); voidOngui () {Display (root); } voidDisplay (node node) {Guilayout.label ("Value:"); Node.interestingvalue= Guilayout.textfield (Node.interestingvalue, Guilayout.width ( $)); Guilayout.beginhorizontal (); Guilayout.space ( -); Guilayout.beginvertical (); foreach(varChildinchNode.children) Display (child); if(Guilayout.button ("ADD Child")) Node.children.Add (NewNode ()); Guilayout.endvertical (); Guilayout.endhorizontal (); }}
View Code
The workaround uses the Iserializationcallbackreceiver interface: lets you generate a cache variable to serialize instead of serializing a tree type directly
usingUnityengine;usingSystem.Collections.Generic;usingSystem; Public classBehaviourwithtree:monobehaviour, iserializationcallbackreceiver{//Node class that's used at runtime Public classNode { Public stringInterestingvalue ="value"; Publiclist<node> children =NewList<node>(); } //node class that we 'll use for serialization[Serializable] Public structSerializablenode { Public stringInterestingvalue; Public intChildCount; Public intIndexoffirstchild; } //The root of what we use at Runtime. Not serialized.Node root =NewNode (); //The field we give unity to serialize. PublicList<serializablenode>Serializednodes; Public voidonbeforeserialize () {//Unity is about to read the Serializednodes field ' s contents. Lets make sure//we write out the correct data into this field "just in time".serializednodes.clear (); Addnodetoserializednodes (root); } voidAddnodetoserializednodes (Node N) {varSerializednode =NewSerializablenode () {Interestingvalue=N.interestingvalue, ChildCount=N.children.count, Indexoffirstchild= serializednodes.count+1 }; Serializednodes.add (Serializednode); foreach(varChildinchN.children) addnodetoserializednodes (child); } Public voidonafterdeserialize () {//Unity has just written new data into the Serializednodes field. //Let's populate our actual runtime data with those new values. if(Serializednodes.count >0) Root= Readnodefromserializednodes (0); ElseRoot=NewNode (); } Node Readnodefromserializednodes (intindex) { varSerializednode =serializednodes [index]; varChildren =NewList<node> (); for(intI=0; I!= Serializednode.childcount; i++) Children. ADD (Readnodefromserializednodes (Serializednode.indexoffirstchild+i)); return NewNode () {Interestingvalue=Serializednode.interestingvalue, children=children}; } voidOngui () {Display (root); } voidDisplay (node node) {Guilayout.label ("Value:"); Node.interestingvalue= Guilayout.textfield (Node.interestingvalue, Guilayout.width ( $)); Guilayout.beginhorizontal (); Guilayout.space ( -); Guilayout.beginvertical (); foreach(varChildinchNode.children) Display (child); if(Guilayout.button ("ADD Child")) Node.children.Add (NewNode ()); Guilayout.endvertical (); Guilayout.endhorizontal (); }}
View Code
Be careful with serialization, because serialization is not run on the main thread!
Unity Serialization Summary