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

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,617
    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 ;)