Populate Editor Popup with Selected Gameobject Functions

I have a gameobject that a user can select in the editor although I want to be able to access its public functions via the property drawer since its custom.


My intention is to have a drop down menu that displays all the objects classes and functions that a user can select via a popup drop down. Kinda similar to how the event component works

177159-capture.png


I know I can usually do that by getting all MonoBehaviour components via GetComponents but since this is a property drawer, it doesn’t inherit from MonoBehaviou. Meaning I don’t have access to those functions.


This is what i have so far

        EditorGUI.PropertyField(rect, prop, GUIContent.none);
        
        if (startTriggerProp.objectReferenceValue != null) {
            // Create popup drop down list with public functions of selected gameobject
        }

Here are few ideas to try / develop further (this more like pseudocode):

1)

If you just want the user to be able to select methods in edit mode to be invoked in the actual game then the easiest is to add out-of-the-box component where it looks like public UnityEvent unityEvent; variable. This has already default drawer where you can select the component and it gives you a list of available public methods methods (something like EventTrigger your screen capture is taken from). You can then invoke the methods via that event.

If you define the unityevent in the Editor code then you get the serialized property from it like this:

SerializedProperty serializedEvent =  new SerializedObject(this).FindProperty("unityEvent");

After that just put in inside OnGUI this:

EditorGUI.PropertyField(positionRect, serializedEvent);

Note: The UnityEvent is now only in the Editor code, not in the actual game code. So in the end you need UnityEvent to some Monobehavior so you can store the actual unityevent. Actually easiest way would be to already have it in some component and just get reference to it from the editor.

2)

Otherwise you need to use reflection yourself to get the MethodInfo’s from the class, something like like this:

First make the field for the Component you want the methods from so you can drag & drop the needed component:

Component c = EditorGUI.Objectfield(positionRect, c, typeof(Component));

then get the method infos to array (notice: don’t call this in every OnGUI, only when c not null and is changed)

MethodInfo[] methodInfos = c.GetType().
                           .GetMethods(BindingFlags.Public | BindingFlags.Instance);

then get method names to a List from the methodinfos array

List<string> methodNames = new List<string>();
foreach (MethodInfo m in methodInfos) methodNames.Add(m.Name);

then use EditorGUI.Popup to show the string list (using .ToArray() ) and handle the selection.

Because the indexing of string and methodinfo arrays matches (well this not guaranteed way but you can make it better) you can use the same selected int index to reference to the actual methodinfo to do what you want with it.

Note:

Above examples were more like pseudo code but I have used similar methodology in my own editor components so at least the ideas should be ok.

Hope some of this is help to you and you get everything working!

Added note:

You actually asked about to get the component references… This is quite easy to get:

GameObject inspectedObjet = EditorGUI.Objectfield(positionRect, inspectedObjet  typeof(GameObject));

and then just get the Component rererences:

Component[] comps = inspectedObjet.GetComponents<Component>();

after that iterate the components and use earlier shown reflection