- Home /
Unity 4.6 - Editor Scripting - Add Reflection Method as a Persistent Listener
What am I trying to do?
I'm current trying to use an EditorWindow to quickly add all of the OnClick Events to my Selectable components. Rather then me having to do it all manually.
I'm using UnityEventTools and AddPersistentListener, but I'm running into a few issues when I try to add a Reflection Method as a PersistentListener.
Error
ArgumentException: Could not register callback <>m__1 on MenuWindow+<OnGUI>c__AnonStorey0. The class MenuWindow+<OnGUI>c__AnonStorey0 does not derive from UnityEngine.Object
UnityEngine.Events.UnityEventBase.ValidateRegistration (System.Reflection.MethodInfo method, System.Object targetObj, PersistentListenerMode mode, System.Type argumentType) (at C:/BuildAgent/work/d63dfc6385190b60/Runtime/Export/UnityEvent.cs:783)
UnityEngine.Events.UnityEventBase.ValidateRegistration (System.Reflection.MethodInfo method, System.Object targetObj, PersistentListenerMode mode) (at C:/BuildAgent/work/d63dfc6385190b60/Runtime/Export/UnityEvent.cs:772)
UnityEngine.Events.UnityEventBase.RegisterVoidPersistentListener (Int32 index, UnityEngine.Events.UnityAction call) (at C:/BuildAgent/work/d63dfc6385190b60/Runtime/Export/UnityEvent.cs:850)
UnityEngine.Events.UnityEventBase.AddVoidPersistentListener (UnityEngine.Events.UnityAction call) (at C:/BuildAgent/work/d63dfc6385190b60/Runtime/Export/UnityEvent.cs:840)
UnityEditor.Events.UnityEventTools.AddVoidPersistentListener (UnityEngine.Events.UnityEventBase unityEvent, UnityEngine.Events.UnityAction call) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/Utils/UnityEventTools.cs:110)
MenuWindow.OnGUI () (at Assets/_UnitySimplificationLibrary/Editor/Windows/MenuWindow.cs:79)
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
My Editor OnGUI Button Script
if (_menus.Count > 0)
{
foreach (MenuHelper menu in _menus.Where(temp => temp.MyMenu != null))
{
menu.MyMenu.name = EditorGUILayout.TextField("Name: ", menu.MyMenu.name);
}
if (GUILayout.Button("Detect Selectable Event Methods"))
{
foreach (MenuHelper menu in _menus)
{
if (menu.MyMenu == null)
continue;
foreach (Selectable selectable in menu.MyMenu.Selectables.Values)
{
if (selectable == null)
continue;
Type type = menu.MyMenu.GetType();
MethodInfo methodInfo = type.GetMethod("On" + selectable.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (methodInfo == null)
continue;
Debug.Log(string.Format("[{0}] - On{1} [{2}]", type.Name, selectable.name, methodInfo));
if (selectable is Button)
{
var button = selectable as Button;
methodInfo.Invoke(menu.MyMenu, null);
UnityEventTools.AddVoidPersistentListener(button.onClick, () => methodInfo.Invoke(menu.MyMenu, null));
}
}
}
}
}
So I've figured out part of my issue, essentially because I'm making a delegate It isn't working properly, unfortunately I don't know of any way of using a reflection method in this instance without making it a delegate...
Answer by unimechanic · Oct 06, 2014 at 09:30 PM
You can ask in the Beta group, where our developers could help.
Thanks, I may do that. Although I think what I was trying to accomplish is impossible atleast in the method I was using to do it. $$anonymous$$y reasoning being in order to use a method obtained via reflection I would need to use an anonymous function to call it.
i.e.
() => methodInfo.Invoke(menu.$$anonymous$$y$$anonymous$$enu, null)
Which is completely contradictory to what the Persistent Listener is used for.
The persistent listener is used to store a function it knows exists. Whereas I was just creating a fictitious function that doesn't really exist. There may be a way of doing this, but as of right now I have no idea what it is.
Anyways, I'm just relieved that someone finally responded.
Cheers and hope you have a great day!