Search Unity

Custom Editor does not show enum options

Discussion in 'Scripting' started by ronshalev3d, Jan 27, 2020.

  1. ronshalev3d

    ronshalev3d

    Joined:
    Apr 30, 2019
    Posts:
    21
    I have the following script

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.Video;
    6. using UnityEditor;
    7.  
    8.  
    9. public class StreamVideo : MonoBehaviour {  
    10.  
    11.     public InputType VideoInputType;
    12.     public VideoClip Video;
    13.     public string VideoName;  
    14.     public enum InputType {Clip, Name}
    15. ....
    16. }
    17.  
    18. [CustomEditor(typeof(StreamVideo))]
    19. public class StreamVideoEditor : Editor
    20. {
    21.     public override void OnInspectorGUI()
    22.     {
    23.         serializedObject.Update();
    24.         EditorGUILayout.PropertyField (serializedObject.FindProperty ("VideoInputType"));
    25.        StreamVideo.InputType VideoInputType =  (StreamVideo.InputType) serializedObject.FindProperty("VideoInputType").enumValueIndex;
    26.        
    27.         switch (VideoInputType)
    28.         {
    29.             case StreamVideo.InputType.Clip:
    30.                 EditorGUILayout.PropertyField(serializedObject.FindProperty("Video"));
    31.                 break;
    32.  
    33.             case StreamVideo.InputType.Name:
    34.                 EditorGUILayout.PropertyField(serializedObject.FindProperty("VideoName"));
    35.                 break;
    36.        }
    37.     }
    38. }
    39.  
    the problem is:
    once the lines
    Code (csharp):
    1. EditorGUILayout.PropertyField (serializedObject.FindProperty ("VideoInputType"));
    2.        StreamVideo.InputType VideoInputType =  (StreamVideo.InputType) serializedObject.FindProperty("VideoInputType").enumValueIndex;
    are implemented, I can see the enum in the editor, but its stuck on the 1st option of the enum and cannot be changed.
    I also tried to remove the script and put it again to refresh the visuality, its persistent.

    what did i do wrong?
    I'm using the assistance of this thread
    https://answers.unity.com/questions/1322418/inspector-showhide-property-within-custom-class-us.html
     
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,325
    Do the following changes:
    1. Cache the value of serializedObject.FindProperty("VideoInputType") to a field during OnEnable and use this in OnInspectorGUI.
    2. Add serializedObject.ApplyModifiedProperties() at the end of OnInspectorGUI.
     
  3. ronshalev3d

    ronshalev3d

    Joined:
    Apr 30, 2019
    Posts:
    21
    Hi SisusCo and thanks for helping.

    I tried this too.

    Code (CSharp):
    1. [CustomEditor(typeof(StreamVideo))]
    2. public class StreamVideoEditor : Editor
    3. {
    4.  
    5.     SerializedProperty input;
    6.  
    7.     private void OnEnable()
    8.     {
    9.         input = serializedObject.FindProperty("VideoInputType");
    10.     }
    11.     public override void OnInspectorGUI()
    12.     {
    13. //i tried with and without any of those 2 lines
    14.         StreamVideo _target = (StreamVideo)target;
    15.         serializedObject.Update();
    16.  
    17.         EditorGUILayout.PropertyField (input);
    18.     }
    19. }
    the expecter results here are simply to reveal the enum dropdown.
    while the enum foes appear, the issue still persists and only the 1st option is selectable.
    same happens with a fresh new enum i created and tested.

    I'm using unity 2019.2.16f1
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    1) wasn't necessary, but it's in general a good idea. 2) was the important part.

    You can reduce your script to:

    Code (csharp):
    1. [CustomEditor(typeof(StreamVideo))]
    2. public class StreamVideoEditor : Editor
    3. {
    4.     public override void OnInspectorGUI()
    5.     {
    6.         EditorGUILayout.PropertyField (serializedObject.FindProperty ("VideoInputType"));
    7.         serializedObject.ApplyModifiedProperties();
    8.     }
    9. }
    That'll work.

    Notes:
    serializedObject.Update takes your object and applies it to the serialized object. It's necessary if the object's values gets changed outside of the editor.

    serializedObject.ApplyModifiedProperties transfers the values you've updated in the inspector to the object you're editing, so it's absolutely necessary to make things work.
     
  5. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,325
    @nirharpaz3d

    You forgot to add the serializedObject.ApplyModifiedProperties part. This works:
    Code (CSharp):
    1. using UnityEditor;
    2.  
    3. [CustomEditor(typeof(StreamVideo))]
    4. public class StreamVideoEditor : Editor
    5. {
    6.     SerializedProperty input;
    7.     SerializedProperty video;
    8.     SerializedProperty videoName;
    9.  
    10.     private void OnEnable()
    11.     {
    12.         input = serializedObject.FindProperty("VideoInputType");
    13.         video = serializedObject.FindProperty("Video");
    14.         videoName = serializedObject.FindProperty("VideoName");
    15.     }
    16.  
    17.     public override void OnInspectorGUI()
    18.     {
    19.         EditorGUILayout.PropertyField(input);
    20.  
    21.         var videoInputType = (StreamVideo.InputType)input.enumValueIndex;
    22.         switch(videoInputType)
    23.         {
    24.             case StreamVideo.InputType.Clip:
    25.                 EditorGUILayout.PropertyField(video);
    26.                 break;
    27.             case StreamVideo.InputType.Name:
    28.                 EditorGUILayout.PropertyField(videoName);
    29.                 break;
    30.         }
    31.  
    32.         serializedObject.ApplyModifiedProperties();
    33.     }
    34. }

    Yeah, I was not sure that changes made though SerializedProperties would immediately get applied to the SerializedObject without ApplyModifiedProperties being called first. In hindsight it would be pretty strange if it didn't since it's SerializedObject.ApplyModifiedProperties and not SerializedProperty.ApplyModifiedProperties. So I just tried it and can confirm that step 1 was indeed not necessary.