Search Unity

Undo and Serialization

Discussion in 'Immediate Mode GUI (IMGUI)' started by SweetJV, Aug 22, 2016.

  1. SweetJV

    SweetJV

    Joined:
    Aug 22, 2016
    Posts:
    11
    I have a component that has two sets of data:

    - "real" data, which will be used at runtime
    - "editor" data, that is useless at runtime, but is needed to store things while editing the component (ex. selections, etc)

    The "real" data fields are marked with [SerializeField], while the "editor" data is not. The idea here is to save the memory footprint for run-time by letting those fields be null/empty in the final build, but become populated during editing.

    However, I now suspect this may be incompatible with the Undo system. In my custom editor I'm using Undo.RecordObject. And while I can undo/redo the operations, it seems like my "editor" data is getting nuked.

    So, I'm wondering two things:

    1. Am I correct in thinking that the undo system uses serialization, and so of course my editor data will get nuked. Or, is there some way to preserve that data?
    2. If I do have to serialize the "editor" data for undo/redo to work, is there a common solution for stripping this kind of data out of the final build?

    Or, maybe I'm completely wrong and I just have a bug that's nuking my data during undo/redo. Anyway, I'd love to hear any thoughts or advice on this.
     
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    Hi

    1: Yes, Undo.RecordObject relies on serialization

    2: I don't know of a way to serialize data for the editor only, so my only suggestion for now would be to move the editor data somewhere else if possible.
     
  3. SweetJV

    SweetJV

    Joined:
    Aug 22, 2016
    Posts:
    11
    Good to know. Thanks for the info!

    For anyone that runs into a similar situation, it turns out I had a couple problems going on. My biggest one was that for my editor selection data I was using a custom list class, derived from list, which exposed additional helper methods. Something like this:

    Code (csharp):
    1.  
    2. public class SelectedItemList : List<SelectedItem>
    3. {
    4.     public void InvertSelection( List<Item> items )
    5.     {
    6.         // Code that inverts our selection
    7.     }
    8. }
    9.  
    Unfortunately, Unity doesn't serialize derived Lists even if you mark it with [SerializeField]. I knew about that limitation when I created the class, but figured that was fine since I didn't want my selection data saved anyway. But to be compatible with Undo, I guess you have to be compatible with serialization.

    So, I had to refactor my class to use a vanilla List<SelectedItem>. However, I also figured out that you can create an extension method for a concrete version of a generic. So, I was able to re-create my helper methods, like so:

    Code (csharp):
    1.  
    2. public static class SelectedItemListExt
    3. {
    4.     public static void InvertSelection( this List<SelectedItem> selected, List<Item> items )
    5.     {
    6.         // Code that inverts our selection
    7.     }
    8. }
    9.  
    It would be super great if Unity could upgrade their serialization for collections. But until then, I guess this is a passable work-around.