@@ -13,7 +13,18 @@ { private Dictionary<string, State> m_States = new Dictionary<string, State>(); // Find internal methods with reflection - private static MethodInfo findMethod = typeof(UnityEventBase).GetMethod("FindMethod", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, new Type[] { typeof(string), typeof(object), typeof(PersistentListenerMode), typeof(Type) }, null); + private static MethodInfo findMethod = typeof(UnityEventBase).GetMethod( + "FindMethod", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, + new Type[] { + typeof(string), +#if UNITY_2020_1_OR_NEWER + typeof(Type), +#else + typeof(object), +#endif + typeof(PersistentListenerMode), + typeof(Type), + }, null); private static MethodInfo temp = typeof(GUIContent).GetMethod("Temp", BindingFlags.NonPublic | BindingFlags.Static, null, CallingConventions.Standard, new Type[] { typeof(string) }, null); private static PropertyInfo mixedValueContent = typeof(EditorGUI).GetProperty("mixedValueContent", BindingFlags.NonPublic | BindingFlags.Static); private Styles m_Styles; @@ -26,7 +37,14 @@
private static string GetEventParams(UnityEventBase evt) { - var method = (MethodInfo)findMethod.Invoke(evt, new object[] { "Invoke", evt, PersistentListenerMode.EventDefined, null }); + var method = (MethodInfo)findMethod.Invoke(evt, new object[] { + "Invoke", +#if UNITY_2020_1_OR_NEWER + evt.GetType(), +#else + evt, +#endif + PersistentListenerMode.EventDefined, null }); var stringBuilder = new StringBuilder(); stringBuilder.Append(" ("); var array = ((IEnumerable<ParameterInfo>)method.GetParameters()).Select(x => x.ParameterType).ToArray(); @@ -306,6 +324,67 @@ m_LastSelectedIndex = list.index; }
+#if UNITY_2020_1_OR_NEWER + private static UnityEventBase GetDummyEventStep(string propertyPath, System.Type propertyType, BindingFlags bindingFlags) + { + UnityEventBase dummyEvent = null; + + while (propertyPath.Length > 0) + { + if (propertyPath.StartsWith(".")) + propertyPath = propertyPath.Substring(1); + + string[] splitPath = propertyPath.Split(new char[] { '.' }, 2); + + FieldInfo newField = propertyType.GetField(splitPath[0], bindingFlags); + + if (newField == null) + break; + + propertyType = newField.FieldType; + if (propertyType.IsArray) + { + propertyType = propertyType.GetElementType(); + } + else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>)) + { + propertyType = propertyType.GetGenericArguments()[0]; + } + + if (splitPath.Length == 1) + break; + + propertyPath = splitPath[1]; + if (propertyPath.StartsWith("Array.data[")) + propertyPath = propertyPath.Split(new char[] { ']' }, 2)[1]; + } + + if (propertyType.IsSubclassOf(typeof(UnityEventBase))) + dummyEvent = System.Activator.CreateInstance(propertyType) as UnityEventBase; + + return dummyEvent; + } + + private static UnityEventBase GetDummyEvent(SerializedProperty property) + { + UnityEngine.Object targetObject = property.serializedObject.targetObject; + if (targetObject == null) + return new UnityEvent(); + + UnityEventBase dummyEvent = null; + Type targetType = targetObject.GetType(); + BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + do + { + dummyEvent = GetDummyEventStep(property.propertyPath, targetType, bindingFlags); + bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic; + targetType = targetType.BaseType; + } while (dummyEvent == null && targetType != null); + + return dummyEvent ?? new UnityEvent(); + } +#else private static UnityEventBase GetDummyEvent(SerializedProperty prop) { var type = Type.GetType(prop.FindPropertyRelative("m_TypeName").stringValue, false); @@ -313,6 +392,7 @@ return new UnityEvent(); return Activator.CreateInstance(type) as UnityEventBase; } +#endif
private static IEnumerable<ValidMethodMap> CalculateMethodMap(UnityEngine.Object target, Type[] t, bool allowSubclasses) { @@ -365,7 +445,14 @@
private static MethodInfo GetMethod(UnityEventBase dummyEvent, string methodName, UnityEngine.Object uObject, PersistentListenerMode modeEnum, Type argumentType) { - return (MethodInfo)findMethod.Invoke(dummyEvent, new object[] { methodName, uObject, modeEnum, argumentType }); + return (MethodInfo)findMethod.Invoke(dummyEvent, new object[] { + methodName, +#if UNITY_2020_1_OR_NEWER + uObject?.GetType(), +#else + uObject, +#endif + modeEnum, argumentType }); }
private static GenericMenu BuildPopupList(UnityEngine.Object target, UnityEventBase dummyEvent, SerializedProperty listener)
|