Search code examples
c#unity-game-engineunity-editor

Edit existing editor inspector?


I want to write custom inspector for one of my scripts. All I want to change is input method for one of the strings to popup (so instead of writing whole string everytime I choose it from premade list of strings, like enums). But the thing is it's VERY long inspector with a lot of variables and rewriting everything just for this one input just doesn't click for me. I'm very happy with how default inspector shows all the fields, expect this one string I want to change. Is there a way to do it without rewriting whole inpector on your own?


Solution

  • Instead of implementing an entire new Inspector which is a bit overkill as you mentioned you should rather use a PropertyDrawer for that field only.

    It depends a lot where you get the available options from. In general I would for example impement a custom PropertyAttribute

    [AttributeUsage(AttributeTargets.Field)]
    public class SelectionAttribute : PropertyAttribute
    {
        public int Index;
    }
    

    with a custom PropertyDrawer and place this drawer in a folder called Editor

    [CustomPropertyDrawer(typeof(SelectionAttribute))]
    public class SelectionAttributDrawer : PropertyDrawer
    {
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            // The 6 comes from extra spacing between the fields (2px each)
            return EditorGUIUtility.singleLineHeight;
        }
    
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
    
            if (property.propertyType != SerializedPropertyType.String)
            {
                EditorGUI.HelpBox(position, "Only works with string", MessageType.Error);
                return;
            }
    
            //TODO: somewhere you have to get the options from
            var options = new[] { "A", "B", "C", "D", "E" };
    
            if (options == null || options.Length < 1)
            {
                EditorGUI.HelpBox(position, "No options available", MessageType.Error);
                return;
            }
    
            var selectionAttribute = (SelectionAttribute)attribute;
    
            EditorGUI.BeginProperty(position, label, property);
    
            EditorGUI.BeginChangeCheck();
            selectionAttribute.Index = EditorGUI.Popup(position, options.ToList().IndexOf(property.stringValue), options);
            if (EditorGUI.EndChangeCheck())
            {
                property.stringValue = options[selectionAttribute.Index];
            }
    
            EditorGUI.EndProperty();
        }
    }
    

    Now you can use it across your project in multiple classes like e.g.

    public class Example : MonoBehaviour
    {
        [Selection] public string MySelection;
    
        private void Start()
        {
            Debug.Log(MySelection);
        }
    }
    

    without the need for a custom editor

    enter image description here