public static bool IsPersistantListenerValid(UnityEventBaseEx dummyEvent, string methodName, Object uObject, UnityEngine.Events.PersistentListenerMode modeEnum, Type argumentType)
        {
            if (uObject == null || string.IsNullOrEmpty(methodName))
            {
                return(false);
            }

            return(dummyEvent.FindMethod(methodName, uObject.GetType(), modeEnum, argumentType) != null);
        }
        static GenericMenu BuildPopupList(Object target, UnityEventBaseEx dummyEvent, SerializedProperty listener)
        {
            //special case for components... we want all the game objects targets there!
            var targetToUse = target;

            if (targetToUse is Component)
            {
                targetToUse = (target as Component).gameObject;
            }

            // find the current event target...
            var methodName = listener.FindPropertyRelative(kMethodNamePath);

            var menu = new GenericMenu();

            menu.AddItem(new GUIContent(kNoFunctionString),
                         string.IsNullOrEmpty(methodName.stringValue),
                         ClearEventFunction,
                         new UnityEventFunction(listener, null, null, UnityEngine.Events.PersistentListenerMode.EventDefined));

            if (targetToUse == null)
            {
                return(menu);
            }

            menu.AddSeparator("");

            // figure out the signature of this delegate...
            // The property at this stage points to the 'container' and has the field name
            Type delegateType = dummyEvent.GetType();

            // check out the signature of invoke as this is the callback!
            MethodInfo delegateMethod         = delegateType.GetMethod("Invoke");
            var        delegateArgumentsTypes = delegateMethod.GetParameters().Select(x => x.ParameterType).ToArray();

            GeneratePopUpForType(menu, targetToUse, false, listener, delegateArgumentsTypes);
            if (targetToUse is GameObject)
            {
                Component[] comps          = (targetToUse as GameObject).GetComponents <Component>();
                var         duplicateNames = comps.Where(c => c != null).Select(c => c.GetType().Name).GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
                foreach (Component comp in comps)
                {
                    if (comp == null)
                    {
                        continue;
                    }

                    GeneratePopUpForType(menu, comp, duplicateNames.Contains(comp.GetType().Name), listener, delegateArgumentsTypes);
                }
            }

            return(menu);
        }
        static string GetEventParams(UnityEventBaseEx evt)
        {
            var methodInfo = evt.FindMethod("Invoke", evt.GetType(), UnityEngine.Events.PersistentListenerMode.EventDefined, null);

            var sb = new StringBuilder();

            sb.Append(" (");

            var types = methodInfo.GetParameters().Select(x => x.ParameterType).ToArray();

            for (int i = 0; i < types.Length; i++)
            {
                sb.Append(types[i].Name);
                if (i < types.Length - 1)
                {
                    sb.Append(", ");
                }
            }
            sb.Append(")");
            return(sb.ToString());
        }
        public void OnGUI(Rect position)
        {
            if (m_ListenersArray == null || !m_ListenersArray.isArray)
            {
                return;
            }

            m_DummyEvent = GetDummyEvent(m_Prop);
            if (m_DummyEvent == null)
            {
                return;
            }

            if (m_ReorderableList != null)
            {
                var oldIdentLevel = EditorGUI.indentLevel;
                EditorGUI.indentLevel = 0;
                m_ReorderableList.DoList(position);
                EditorGUI.indentLevel = oldIdentLevel;
            }
        }
        static UnityEventBaseEx GetDummyEvent(SerializedProperty prop)
        {
            //Use the SerializedProperty path to iterate through the fields of the inspected targetObject
            Object tgtobj = prop.serializedObject.targetObject;

            if (tgtobj == null)
            {
                return(new UnityEventEx());
            }

            UnityEventBaseEx ret = null;
            Type             ft  = tgtobj.GetType();
            var bindflags        = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

            do
            {
                ret = GetDummyEventHelper(prop.propertyPath, ft, bindflags);
                //no need to look for public members again since the base type covered that
                bindflags = BindingFlags.Instance | BindingFlags.NonPublic;
                ft        = ft.BaseType;
            }while (ret == null && ft != null);
            // go up the class hierarchy if it exists and the property is not found on the child
            return((ret == null) ? new UnityEventEx() : ret);
        }