Search Unity

Custom Editor doesn't apply changes to a prefab instance (changes revert)

Discussion in 'Scripting' started by MDragon, Mar 13, 2014.

  1. MDragon

    MDragon

    Joined:
    Dec 26, 2013
    Posts:
    329
    Edit: Solved. Just forgot to set it dirty... in all my scripts

    Hello, this is actually an older problem that I didn't bother fixing. However, it made me really hesitant to even use custom editors anymore. Actually, when I was making the final modifications to a game, every single time I was trying to edit - say text - of several objects, they would revert in play time to what the prefab's value is. I eventually had to break the prefab connection, which isn't really an efficient option.

    So now that I'm on another new project in its early stages, I was wondering why this problem came up in the first place and how I can avoid it. It would be nice to make custom editors as I go.

    (Also, does this have anything to do with how I have the default inspector at the end of every single one of my editor scripts?)
    Here's an example that I know that stopped working (...if I recall correctly, as I thought I commented it all out rather than deleting it to disable it for final changes):
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(GUIWindow))]
    5. public class E_GUIWindow : Editor
    6. {
    7.     // Flag variable for folds
    8.     bool showDefault = false;    // Show default Inspector?
    9.     bool customTextMesh = false;    // Choose something other than this object's TextMesh
    10.  
    11.     public override void OnInspectorGUI()
    12.     {        
    13.         // Get the current script and its values
    14.         GUIWindow myTarget = (GUIWindow) target;
    15.        
    16.         // Get the current type of Terrain
    17.         myTarget.thisWindow = (GUIWindow.TypeWindow)EditorGUILayout.EnumPopup(
    18.             "Window Type: ", myTarget.thisWindow);
    19.        
    20.         EditorGUILayout.LabelField("-----------"); // Spacer/Separator
    21.        
    22.         // NECESSARY so text wraps around and creates an expanding box
    23.         EditorStyles.textField.wordWrap = true;
    24.        
    25.         // Message to show if GUIWindow hasn't been assigned
    26.         if(myTarget.thisWindow == GUIWindow.TypeWindow.None)
    27.         {    
    28.             EditorGUILayout.HelpBox("This currently does nothing! Absolutely NOTHIN!",
    29.                                     MessageType.Warning);
    30.         }
    31.        
    32.         // Settings if this is a SecretsIndicator window
    33.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.SecretsIndicator)
    34.         {    
    35.             EditorGUILayout.HelpBox("Secrets Indicator! Used for showing information on secrets!",
    36.                                     MessageType.Info);
    37.            
    38.             myTarget.windowName = EditorGUILayout.TextField("Name of Window: ", myTarget.windowName);
    39.             myTarget.message = EditorGUILayout.TextArea("Window Message: ", myTarget.message);
    40.            
    41.         }
    42.        
    43.         // Settings if this is an Info Menu
    44.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.InfoMenu)
    45.         {    
    46.             EditorGUILayout.HelpBox("Used for showing different information!",
    47.                                     MessageType.Info);
    48.            
    49.             // Toggle a non-default Text Mesh or not
    50.             customTextMesh = EditorGUILayout.Foldout(customTextMesh, "Choose Non-Default TextMesh?");
    51.             if(customTextMesh)
    52.             {
    53.                 EditorGUILayout.LabelField("TextMesh: Hover Affect");                        
    54.                 myTarget.thisText = EditorGUILayout.ObjectField(myTarget.thisText,
    55.                                                                 typeof(TextMesh), true) as TextMesh;
    56.             }
    57.            
    58.             EditorGUILayout.LabelField("Window Title");
    59.             myTarget.windowName = EditorGUILayout.TextField(myTarget.windowName);
    60.             EditorGUILayout.LabelField("Message of the Window:");
    61.             myTarget.message = EditorGUILayout.TextArea(myTarget.message);
    62.         }
    63.        
    64.         // Settings if this is a DeleteData window, for deleting all data
    65.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.DeleteData)
    66.         {    
    67.             EditorGUILayout.HelpBox("Window for deleting all data... ='(",
    68.                                     MessageType.Info);
    69.            
    70.             // Toggle a non-default Text Mesh or not
    71.             customTextMesh = EditorGUILayout.Foldout(customTextMesh, "Choose Non-Default TextMesh?");
    72.             if(customTextMesh)
    73.             {
    74.                 EditorGUILayout.LabelField("TextMesh: Hover Affect");                        
    75.                 myTarget.thisText = EditorGUILayout.ObjectField(myTarget.thisText,
    76.                                                                 typeof(TextMesh), true) as TextMesh;
    77.             }
    78.            
    79.             EditorGUILayout.LabelField("Window Title");
    80.             myTarget.windowName = EditorGUILayout.TextField(myTarget.windowName);
    81.             EditorGUILayout.LabelField("Message of the Window:");
    82.             myTarget.message = EditorGUILayout.TextArea(myTarget.message);
    83.         }
    84.        
    85.         // Settings if this is a WorldInner window
    86.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.WorldInner)
    87.         {    
    88.             EditorGUILayout.HelpBox("Used for giving the name and information of the current world",
    89.                                     MessageType.Info);
    90.            
    91.             // Toggle a non-default Text Mesh or not
    92.             customTextMesh = EditorGUILayout.Foldout(customTextMesh, "Choose Non-Default TextMesh?");
    93.             if(customTextMesh)
    94.             {
    95.                 EditorGUILayout.LabelField("TextMesh: Hover Affect");                        
    96.                 myTarget.thisText = EditorGUILayout.ObjectField(myTarget.thisText,
    97.                                                                 typeof(TextMesh), true) as TextMesh;
    98.             }
    99.            
    100.             EditorGUILayout.LabelField("Window Title");
    101.             myTarget.windowName = EditorGUILayout.TextField(myTarget.windowName);
    102.             EditorGUILayout.LabelField("Message of the Window:");
    103.             myTarget.message = EditorGUILayout.TextArea(myTarget.message);
    104.         }
    105.        
    106.         // Settings if this is a Tabbed window
    107.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.Tabular)
    108.         {    
    109.             EditorGUILayout.HelpBox("Used for making tabs",
    110.                                     MessageType.Info);
    111.            
    112.             // Toggle a non-default Text Mesh or not
    113.             customTextMesh = EditorGUILayout.Foldout(customTextMesh, "Choose Non-Default TextMesh?");
    114.             if(customTextMesh)
    115.             {
    116.                 EditorGUILayout.LabelField("TextMesh: Hover Affect");                        
    117.                 myTarget.thisText = EditorGUILayout.ObjectField(myTarget.thisText,
    118.                                                                 typeof(TextMesh), true) as TextMesh;
    119.             }
    120.            
    121.             myTarget.customTabSize = EditorGUILayout.Toggle ("Custom Tab Size?", myTarget.customTabSize);
    122.             if(myTarget.customTabSize) // If using a custom tab size
    123.             {
    124.                 myTarget.sizeMultiplier = EditorGUILayout.RectField(myTarget.sizeMultiplier);
    125.                
    126.                 // Print input
    127.                 if(GUILayout.Button ("Print Input"))
    128.                    {
    129.                     Debug.Log("Current Input: " + myTarget.sizeMultiplier);
    130.                 }
    131.                
    132.                 // Reset the sizeMultiplier to default
    133.                 if(GUILayout.Button ("Reset Size Multiplier?"))
    134.                 {
    135.                     Debug.Log("Default Size: " + myTarget.defaultSize);
    136.                     myTarget.sizeMultiplier = myTarget.defaultSize;
    137.                 }
    138.             }
    139.         } // end else if tabular
    140.         // Settings if this is the Settings window [main menu]
    141.         else if(myTarget.thisWindow == GUIWindow.TypeWindow.Settings)
    142.         {    
    143.             EditorGUILayout.HelpBox("This is the main menu's setting GUI Window",
    144.                                     MessageType.Info);
    145.         }
    146.    
    147.         EditorGUILayout.LabelField("-----------"); // Spacer/Separator
    148.        
    149.         // Code for showing the default Inspector
    150.         showDefault = EditorGUILayout.Foldout(showDefault, "Show Default Inspector");
    151.         if(showDefault)
    152.         {
    153.             DrawDefaultInspector();
    154.         }
    155.     }
    156. }

    This seems like a systematic error, as practically all my past editor scripts have been structured like this. Any possible reasons?
    And thank you for helping, it means a lot to me :D
     
    Last edited: Mar 13, 2014
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Disclaimer: I skipped right past the code. :p

    Are you checking whether changes are made and setting objects dirty when they're detected? If Unity doesn't know that something is dirty I don't think it bothers to save anything for that object. When you enter/exit play mode the scene is serialized and de-serialized, so anything that the Editor doesn't save gets lost, which would explain your issue.
     
  3. MDragon

    MDragon

    Joined:
    Dec 26, 2013
    Posts:
    329
    Thanks, that's exactly it. Ironically, I saw it while searching for why this issue was occurring, but when skimming past I saw that it wasn't "necessary". Yay for taking things out of context while skimming ;)