Search Unity

Undo.RecordObject doesn't save instance of custom class

Discussion in 'Immediate Mode GUI (IMGUI)' started by Pythalic, Sep 8, 2016.

  1. Pythalic

    Pythalic

    Joined:
    Aug 31, 2015
    Posts:
    2
    I am creating an editor window to edit a list of upgrades for my player.

    Code (csharp):
    1. [Serializable]
    2. public class Upgrade{
    3.  
    4.     string name;
    5.     int id;
    6.     Upgrade parent;
    7.  
    8. }
    9.  
    The upgrades need to have a parent upgrade because of dependencies.
    This is my scriptableObject I want to edit

    Code (csharp):
    1. public class UpgradeHierarchy : ScriptableObject {
    2.     public List<Upgrade> upgrades;
    3. }
    4.  
    In the editor script I'm doing something along the lines of:

    Code (csharp):
    1. public class UpdateHierarchyEditor : EditorWindow{
    2.  
    3. void OnGUI()
    4.     {
    5.  
    6.     hierarchy.upgrades[index].name = EditorGUILayout.DelayedTextField("Name", hierarchy.upgrades[index].name as string);
    7.  
    8.     hierarchy.upgrades[index].parent = hierarchy[EditorGUILayout.Popup("Choose parent", hierarchy.upgrades.IndexOf(hierarchy.upgrades[index].parent), upgradeNames.ToArray())];
    9.  
    10. }
    11.  
    I'm basically choosing a name from a list of upgrade names and assigning the parent with the selected index of in the hierarchy to the current upgrade.

    My problem: Using Undo.RecordObject(...) (or EditorUtility.SetDirty(...)) "saves" all properties like name, id or sprite properly except the parent upgrade! The parent upgrade is null after I close and re-open unity. Is there a reason for it, or should I continue to look for errors in my code?
     
  2. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    You have a cycle in your serializable Upgrade class (Upgrade refers to an Upgrade parent), which should be preventing serialization (you cannot set an infinite amount of data in one container). Don't you get a Serialization Depth Limit Exceeded (http://answers.unity3d.com/questions/891985/getting-rid-of-serialization-depth-limit-exceeded.html) ?

    You can make Upgrade non-serializable or store upgrade information differently, such as upgrade name, upgrade type, etc. which will be serializable and prevent the cycle, providing you have a finite number of upgrades available, identified by type or accessible via an array by index or a dictionary by key.

    Tell me what it gives when you try those changes.
     
  3. Pythalic

    Pythalic

    Joined:
    Aug 31, 2015
    Posts:
    2
    I see.

    No I do not get a serialization depth limit exceed. I used to get it when storing the children of an upgrade (as an array) in the upgrade class (basically a tree-like structure).

    I decided to go with storing the index (in the UpdateHierarchy-List) of the parent upgrade. Works quite well, it's just a bit more code.

    Removing an Update out of the list can be a bit complicated though, as I have to update all indices correctly :)