Search Unity

Changing variable name breaks Custom Inspector

Discussion in 'Editor & General Support' started by Fellshadow, May 15, 2015.

  1. Fellshadow

    Fellshadow

    Joined:
    Dec 2, 2012
    Posts:
    169
    I have a custom inspector for a class that works fine, but I wanted to rename the variable that the custom inspector is altering. I go into the class, rename the variable and then go into the custom inspector script and update that script to use the new variable name as well. However, after doing this, whenever I close and reopen Unity, all values I put in will be reset. This only happens when restarting Unity, not when running it in editor or changing focus off the object.

    Can anyone help me figure out what is going on here and how to fix this?

    Name change I'm trying to make (found on line 10 of WeatherManager Class):
    List<WeatherInfo> weatherData to List<WeatherInfo> weatherInfo

    WeatherManager class:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class WeatherManager : MonoBehaviour {
    7.  
    8.     public static WeatherManager instance { get; private set; }
    9.  
    10.     public List<WeatherInfo> weatherData = new List<WeatherInfo>();
    11.  
    12.     public WeatherData myData = StateManager.gameState.weatherData;
    13.  
    14.     WeatherType setWeather;
    15.     public float duration = 0;
    16.  
    17.     private int weatherQueueAmount = 30;
    18.  
    19.     void Awake(){
    20.         instance = this;
    21.     }
    22.  
    23.     //Some unrelated functions here that I cut to save space
    24.  
    25. }
    26. [System.Serializable]
    27. public class Day{
    28.     public List<DayWeather> weatherList = new List<DayWeather>();
    29. }
    30. [System.Serializable]
    31. public class DayWeather{
    32.     public WeatherType weather;
    33.     public float startTime;
    34.     public float duration;
    35.  
    36.     public DayWeather(WeatherType newWeather, float newStart, float newDuration){
    37.         weather = newWeather;
    38.         startTime = newStart;
    39.         duration = newDuration;
    40.     }
    41. }
    42. [System.Serializable]
    43. public class WeatherInfo{
    44.     public float minDuration = 4;
    45.     public float maxDuration = 8;
    46.     public List<NextWeather> nextWeather = new List<NextWeather>();
    47.     public WeatherType elseWeather;
    48. }
    49. [System.Serializable]
    50. public class NextWeather{
    51.     public WeatherType weatherType;
    52.     public List<float> chance = new List<float>();
    53. }
    54. public class WeatherData {
    55.     public List<Day> queuedWeather = new List<Day>();
    56.     public List<Day> weatherHistory = new List<Day>();
    57. }
    58. public enum WeatherType{
    59.     Clear,
    60.     Heatwave,
    61.     Cloudy,
    62.     Precip,
    63.     HeavyPrecip,
    64.     Fog,
    65.     Hail,
    66.     Hurricane
    67. }
    68. public enum Season{
    69.     Spring,
    70.     Summer,
    71.     Fall,
    72.     Winter
    73. }
    74.  

    My Custom Inspector Code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEditor;
    6.  
    7. [CustomEditor(typeof(WeatherManager))]
    8. public class WeatherManagerInspector : Editor {
    9.     //The weather manager data
    10.     WeatherManager weatherManager;
    11.  
    12.     //The Selected weather
    13.     int weatherDataSelected = 0;
    14.     //The selected weather's data
    15.     WeatherInfo selectedWeather;
    16.  
    17.     //The size of the list for next weather
    18.     int nextWeatherSize;
    19.  
    20.     //The size of the weather enum
    21.     int enumSize;
    22.  
    23.     void OnEnable(){
    24.         weatherManager = (WeatherManager)target;
    25.     }
    26.  
    27.     public override void OnInspectorGUI(){
    28.  
    29.         EditorGUILayout.Space ();
    30.  
    31.         //Get the length of the weather enum
    32.         enumSize = System.Enum.GetValues(typeof(WeatherType)).Length;
    33.    
    34.         //Change the list size to equal the enum length
    35.         if(weatherManager.weatherData.Count != enumSize){
    36.             //Debug.Log("Weather Size(" + weatherManager.weatherData.Count + ") does not equal " + size);
    37.             while(weatherManager.weatherData.Count < enumSize){
    38.                 //Debug.Log("increasing size");
    39.                 weatherManager.weatherData.Add(new WeatherInfo());
    40.             }
    41.             while(weatherManager.weatherData.Count > enumSize){
    42.                 weatherManager.weatherData.RemoveAt(weatherManager.weatherData.Count - 1);
    43.             }
    44.         }
    45.  
    46.         //********Create a toolbar for all the different weather types********
    47.         EditorGUILayout.BeginHorizontal();
    48.         weatherDataSelected = GUILayout.SelectionGrid(weatherDataSelected, System.Enum.GetNames(typeof(WeatherType)), 4, EditorStyles.toolbarButton);
    49.         EditorGUILayout.EndHorizontal();
    50.         //********************************************************************
    51.  
    52.         //Add a space
    53.         EditorGUILayout.Space ();
    54.  
    55.         //get the weather data
    56.         selectedWeather = weatherManager.weatherData[weatherDataSelected];
    57.  
    58.         //***********Draw the minimum and maximum duration fields************
    59.         //Begin drawing horizontally
    60.         EditorGUILayout.BeginHorizontal();
    61.         //Draw the minimum duration field
    62.         EditorGUILayout.LabelField("Min Duration", GUILayout.Width(80));
    63.         selectedWeather.minDuration = EditorGUILayout.FloatField("", selectedWeather.minDuration, GUILayout.Width(50));
    64.  
    65.         //Draw the maximum duration field
    66.         EditorGUILayout.LabelField("Max Duration", GUILayout.Width(80));
    67.         selectedWeather.maxDuration = EditorGUILayout.FloatField("", selectedWeather.maxDuration, GUILayout.Width(50));
    68.         //End drawing horizontally
    69.         EditorGUILayout.EndHorizontal();
    70.  
    71.         //Add a space
    72.         EditorGUILayout.Space ();
    73.         //*******************************************************************
    74.         //Get the array size
    75.         nextWeatherSize = weatherManager.weatherData[weatherDataSelected].nextWeather.Count;
    76.         nextWeatherSize = EditorGUILayout.IntField("Potential Next Weather", nextWeatherSize);
    77.  
    78.         //If user tries to make the size less than 0, set to 0
    79.         if(nextWeatherSize < 0){
    80.             nextWeatherSize = 0;
    81.         }
    82.  
    83.         //Change list size
    84.         if(selectedWeather.nextWeather.Count != nextWeatherSize){
    85.             while(selectedWeather.nextWeather.Count < nextWeatherSize){
    86.                 selectedWeather.nextWeather.Add(new NextWeather());
    87.             }
    88.             while(selectedWeather.nextWeather.Count > nextWeatherSize){
    89.                 selectedWeather.nextWeather.RemoveAt(selectedWeather.nextWeather.Count - 1);
    90.             }
    91.         }
    92.         //Add a space
    93.         EditorGUILayout.Space ();
    94.  
    95.         //**********************Draw Weather Data***************************
    96.         for(int i = 0; i < selectedWeather.nextWeather.Count; i++){
    97.             //Set the background color to light blue
    98.             GUI.backgroundColor = new Color(0.85f, 0.88f, 1, .5f);
    99.             //Start drawing vertically
    100.             EditorGUILayout.BeginVertical(EditorStyles.textArea);
    101.             //Get the next weather data
    102.             NextWeather nextData = selectedWeather.nextWeather[i];
    103.             //Start drawing horizontally
    104.             EditorGUILayout.BeginHorizontal();
    105.  
    106.             //********Draw the next weather enum field********
    107.             EditorGUILayout.LabelField("Next Weather: ", GUILayout.MaxWidth(100));
    108.             nextData.weatherType = (WeatherType)EditorGUILayout.EnumPopup(nextData.weatherType, GUILayout.MaxWidth(100));
    109.             //************************************************
    110.  
    111.             //Stop drawing horizontally
    112.             EditorGUILayout.EndHorizontal();
    113.  
    114.             //Get the amount of seasons
    115.             enumSize = System.Enum.GetValues(typeof(Season)).Length;
    116.  
    117.             //Change chance list size
    118.             if(nextData.chance.Count != enumSize){
    119.                 while(nextData.chance.Count < enumSize){
    120.                     nextData.chance.Add(new int());
    121.                 }
    122.                 while(nextData.chance.Count > enumSize){
    123.                     nextData.chance.RemoveAt(nextData.chance.Count - 1);
    124.                 }
    125.             }
    126.  
    127.             //**************Draw the labels for the seasons***************
    128.             EditorGUILayout.BeginHorizontal();
    129.             for(int i2 = 0; i2 < enumSize; i2++){
    130.                 EditorGUILayout.LabelField(System.Enum.GetName(typeof(Season), i2) + " Chance", GUILayout.MinWidth(100));
    131.             }
    132.             EditorGUILayout.EndHorizontal();
    133.             //************************************************************
    134.  
    135.             //***********Draw the input fields for the seasons************
    136.             EditorGUILayout.BeginHorizontal();
    137.             for(int i2 = 0; i2 < enumSize; i2++){
    138.                 nextData.chance[i2] = EditorGUILayout.FloatField("", nextData.chance[i2], GUILayout.MinWidth(100));
    139.             }
    140.             //************************************************************
    141.  
    142.             //Stop drawing horizontally
    143.             EditorGUILayout.EndHorizontal();
    144.             //Stop drawing vertically
    145.             EditorGUILayout.EndVertical();
    146.  
    147.             //Add a space
    148.             EditorGUILayout.Space ();
    149.         }
    150.         //*****************************************************************
    151.  
    152.         //Set the background to the default white
    153.         GUI.backgroundColor = Color.white;
    154.  
    155.         //************Draw the input field for the else weather**************
    156.         EditorGUILayout.BeginHorizontal();
    157.         EditorGUILayout.LabelField("Otherwise:", GUILayout.MaxWidth(70));
    158.         selectedWeather.elseWeather = (WeatherType)EditorGUILayout.EnumPopup(selectedWeather.elseWeather, GUILayout.MaxWidth(100));
    159.         EditorGUILayout.EndHorizontal();
    160.         //*******************************************************************
    161.  
    162.     }
    163.  
    164.     // Use this for initialization
    165.     void Start () {
    166.    
    167.     }
    168.    
    169.     // Update is called once per frame
    170.     void Update () {
    171.    
    172.     }
    173. }
    174.  
     
  2. greg-harding

    greg-harding

    Joined:
    Apr 11, 2013
    Posts:
    524
  3. Fellshadow

    Fellshadow

    Joined:
    Dec 2, 2012
    Posts:
    169
    Thanks for the response!

    However, the issue isn't that I'm losing all the values when I switch the name over - I don't mind that. The issue is that when I fill in the new values, then restart Unity, all of the values are lost.
     
  4. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    You're not marking the object you've edited as dirty after changing values on it, so Unity doesn't detect that the object was changed, and so never saves it. Try calling EditorUtility.SetDirty() on the object in the Inspector.

    Note that this is not an issue if you use the recommended approach to writing custom editors, which is the SerializedObject/SerializedProperty classes. These classes will automatically mark the object as dirty, as well as giving you support for things like multi-object editing and prefab override styling.
     
  5. Fellshadow

    Fellshadow

    Joined:
    Dec 2, 2012
    Posts:
    169
    Thanks, that did the trick!

    It's weird that it worked fine for weeks without that though (and still works with no issues if I change the variable name back).