Search Unity

Custom Inspector not updating until next change

Discussion in 'Scripting' started by AnalogUniverse, Dec 4, 2018.

  1. AnalogUniverse

    AnalogUniverse

    Joined:
    Aug 10, 2018
    Posts:
    64
    Hi All
    Im dabbling with Editor scripting and I have a simple Button class with an idleImage which updates the collider2D when changed. The problem is it updates but its updating to the last change to the idleImage field not the current change. For example lets say I have 3 sprites image1 image2 and image3, the sprite to begin with is image1 and I drag image2 to the inspector, image2 updates in the inspector field and the debug statements in the updateIdleImage method fire, but its not updated in the scene view. The when I drag image3 into the inspector idleImage field, the scene view then updates to image2, if that makes sense.
    Heres my code

    Editor script

    Code (CSharp):
    1. using UnityEditor;
    2.  
    3. [CustomEditor(typeof(MyButton))]
    4.  
    5.  
    6. public class MyButtonEditor : Editor
    7. {
    8.  
    9.     QPUIButton button;
    10.  
    11.     private SerializedProperty textEnabled;
    12.     private SerializedProperty idleImage;
    13.     private SerializedProperty rolloverImage;
    14.     private SerializedProperty eventName;
    15.  
    16.  
    17.     private void OnEnable()
    18.     {
    19.         button = (MyButton)target;
    20.  
    21.         textEnabled = serializedObject.FindProperty("textEnabled");
    22.         idleImage = serializedObject.FindProperty("idleImage");
    23.         rolloverImage = serializedObject.FindProperty("rolloverImage");
    24.         eventName = serializedObject.FindProperty("eventName");
    25.     }
    26.  
    27.  
    28.     public override void OnInspectorGUI()
    29.     {
    30.         serializedObject.UpdateIfRequiredOrScript();
    31.  
    32.         EditorGUILayout.BeginVertical();
    33.  
    34.         EditorGUI.BeginChangeCheck();
    35.         EditorGUILayout.PropertyField(textEnabled);
    36.         if (EditorGUI.EndChangeCheck())
    37.         {
    38.             button.updateText();
    39.         }
    40.  
    41.         EditorGUI.BeginChangeCheck();
    42.         EditorGUILayout.PropertyField(idleImage);
    43.         if (EditorGUI.EndChangeCheck())
    44.         {
    45.             button.updateIdleImage();
    46.         }
    47.  
    48.  
    49.         EditorGUILayout.PropertyField(rolloverImage);
    50.         EditorGUILayout.PropertyField(eventName);
    51.  
    52.         EditorGUILayout.EndVertical();
    53.  
    54.         serializedObject.ApplyModifiedProperties();
    55.  
    56.     }
    57. }
    MY button Code


    Code (CSharp):
    1. [RequireComponent(typeof(SortingGroup))]
    2.  
    3. //mygameobject is simple script that just contains a basic vector3d property and
    4. // extends MonoBehaviour nothing more
    5.  
    6. public class MyButton : MyGameObject
    7. {
    8.     public bool textEnabled;
    9.     public Sprite idleImage;
    10.     public Sprite rolloverImage;
    11.     public string eventName;
    12.  
    13.     private GameObject text;
    14.     protected SpriteRenderer renderer;
    15.  
    16.  
    17.     public void updateIdleImage()
    18.     {
    19.         Transform buttonTransform = transform.Find("button");
    20.  
    21.         if (idleImage)
    22.         {
    23.             Debug.Log("updateCollider called ");
    24.             if (buttonTransform)
    25.             {
    26.                 buttonTransform.parent = null;
    27.                 DestroyImmediate(buttonTransform.gameObject);
    28.                 Debug.Log("button deleted");
    29.             }
    30.  
    31.             GameObject button = new GameObject("button");
    32.             button.transform.parent = transform;
    33.             //button.name = "button";
    34.             button.transform.localPosition = new Vector3(0, 0);
    35.             button.AddComponent<SpriteRenderer>();
    36.             renderer = button.GetComponent<SpriteRenderer>();
    37.             renderer.sprite = idleImage;
    38.             button.AddComponent<PolygonCollider2D>();
    39.  
    40.         }
    41.  
    42. // some additional methods which don't effect the above code
    43.     }
    44. }
    Any help as always greatly appreciated
     
    Last edited: Dec 4, 2018
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    AnalogUniverse likes this.
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    You need to stick an ApplyModifiedProperties() in before you call updateIdleImage:

    Code (csharp):
    1.         EditorGUI.BeginChangeCheck();
    2.         EditorGUILayout.PropertyField(textEnabled);
    3.         if (EditorGUI.EndChangeCheck())
    4.         {
    5.             serializedObject.ApplyModifiedProperties();
    6.             button.updateText();
    7.         }
    What ApplyModifiedProperties does is to write the changes you have made to the SerializedObject to the actual object it represents. So since you call
    button.updateIdleImage();
    before you call
    serializedObject.ApplyModifiedProperties();
    , your MyButton will still have the last image when you try to update it.
     
    flashframe and AnalogUniverse like this.
  4. AnalogUniverse

    AnalogUniverse

    Joined:
    Aug 10, 2018
    Posts:
    64
    Thanks Baste That makes sense works perfectly ! :)