Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Can custom field types be serialized?

Discussion in 'Scripting' started by llde_chris, Aug 17, 2009.

  1. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    Hi,

    We created a custom inspector (EditorWindow) that enables editing of some of our custom fixed point value types. Editing and viewing the values work well enough; however, it seems that the values are not serialized in the same way that the regular types are.

    We can view both floats and fixed point in our custom editor window, but upon running the program the fixed point reverts to whatever it was in the beginning while the floating point values retain the new edited values.

    It seems Unity only serializes public types it knows about (makes sense), but is there some way to hook into the system to save our custom types so we can edit them in the same way in the editor? It would seem so natural to have the facility since it's so easy to add custom inspectors.
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Yes its possible. The requirement is that the class is serializable if it does not extend one of the classes that work out of the box
     
  3. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    We've tried adding [System.Serializable], but it does not seem to work for structs.

    Is there another way to specify/control serialization for structs? It's for a fixed point data type, so changing it into a class would introduce a lot of possible bugs when people try to treat it as a regular value type.

    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public struct fixed_point : ISerializable
    4. {
    5.     public long Raw;
    6.  
    7.     public fixed_point(SerializationInfo serInfo,
    8.         StreamingContext streamContext)
    9.     {
    10.         Raw = serInfo.GetInt32("Raw");
    11.     }
    12.  
    13.     void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    14.     {
    15.         info.AddValue("Raw", Raw);
    16.     }
    17. }
    18.  
    19.  
    With the above code neither the ISerializable interface nor the serialization constructor are called by Unity. The Raw public variable doesn't appear in the inspector either, even if we change fixed_point into a class.

    Is there another way to tell the Inspector to save the public long Raw above after we edit it in our custom inspector?
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    You could make it part of the custom inspector
     
  5. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    Hmmm, offhand to make that work I think we would need a separate data store from what the Inspector uses, or declare companion strings for each fixed_point member variable just so that Unity would have somewhere to store the edited values. Then every time the game starts we convert from the string into the long value.

    Code (csharp):
    1.  
    2. public struct fixed_point
    3. {
    4.     public long Raw;
    5.     public string Raw_storage;
    6.  
    7.     public void InitFromAwake()
    8.     {
    9.         Raw = long.Parse(Raw_storage);
    10.     }
    11.  
    12.     ...
    13.  
    Then call InitFromAwake for every single instance of fixed_point that should be editable from the Inspector each time a GameObject is started.

    Workable I guess, just... rather awkward =/
     
  6. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    You can use a Property for your Raw (long) value, and then perform the string conversion (with FormatException handling) the first time it is requested.

    Should make it a _bit_ nicer to use, but it is still a pain...

    -Jeremy
     
  7. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    Ah, right, that'll get rid of a lot of the mess of this approach.

    Thanks Jeremy and dreamora!
     
  8. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    FWIW, custom structs won't display in the editor by default so you're not missing anything. I just wanted to point that out so you knew for sure.
     
  9. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    Hi HiggyB,

    Yup, we built an inspector to display the custom struct... that contained a variable type that wasn't saved by the inspector anyway. :D

    Oh well...