Generic List EditorGUI

I am trying to streamline the EditorGUI process by creating some generic functions that I use often in most of my Editor GUI classes. I’m sort of stuck on this one, though: I am trying to create a generic List<> GUI. I know how to do it when I know the type of the List, but I’m trying to make this as generic as possible.

Here’s an example of the GUI when typed strictly to strings:

        bool StringListGUI (bool open, string s, List<string> list){
                bool b = EditorGUILayout.Foldout(open, s);
               
                if(b){
                        EditorGUI.indentLevel++;
                       
                                for(int i = 0; i < list.Count; i++){
                                       
                                        EditorGUILayout.BeginHorizontal();
                                                list[i] = EditorGUILayout.TextField(list[i]);
                                                if(RemoveButton()){
                                                        list.RemoveAt(i);
                                                        i--;
                                                }
                                        EditorGUILayout.EndHorizontal();
                                }
                               
                                EditorGUILayout.BeginHorizontal();
                                        string n = EditorGUILayout.TextField("");
                                        if(n != "") list.Add(n);
                                EditorGUILayout.EndHorizontal();
                       
                        EditorGUI.indentLevel--;
                }
               
                return b;
        }
       
        bool RemoveButton (){
                if(GUILayout.Button("X", GUILayout.Width(30))) return true;
                return false;
        }

I would like to convert that into something which could be sent a List of any type. I’m alright with having a button to create a new object rather than the dynamic field I have in there currently. Any help is greatly appreciated!

Hrm, I just realized that a hitch might be in actually laying out the GUI for the generic object. I’m going to just build around this. Any insights still appreciated, though.

There are a few things there which you’ll need to do differently for different object types - you could put the abstraction at various levels, but to begin with let’s say:

A) Convert to string for display
B) Convert from string

You can make an abstract class defining these methods, then instantiate specializations of the class to handle specific types. You can store those in a list or perhaps a dictionary, and dynamically search for the right handler specialization for whatever type is stored in the list. (B) needs to return Object, which you’ll need to cast to the right type before storing in the list, and in order to do that I think you need a ‘class’ type constraint on your template argument.

You can also encapsulate at a higher level, moving the presentation of the TextField into the handler class, which allows you to use different presentation for different types, too - such as using sliders for floats, spin boxes for ints, and so on. If you do this you’ll probably end up with just one virtual method which both presents the old value and returns the new value, like the Unity GUI functions generally do. You could also move the store-into-list functionality into the handler, but that will be trickier due to the generics.