public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { if (GetPersistentCallCount(property) == 0) { return(18 * 2); } UnityEventDrawer eventDrawer = new UnityEventDrawer(); return(eventDrawer.GetPropertyHeight(property, label)); }
bool DrawUnityEvent(UnityEventDrawer drawer, Rect position, SerializedProperty property, GUIContent label) { styleLabel.alignment = TextAnchor.MiddleLeft; styleLabel.fixedHeight = header.fixedHeight; System.Type[] typeArguments = default; if (property.propertyType == SerializedPropertyType.Generic) { var type = property.serializedObject.targetObject.GetFieldValue(property.propertyPath).GetType(); if (type.IsGenericType) { typeArguments = type.GetGenericArguments(); } //var genericType = type.GetGenericTypeDefinition(); } if (property.isExpanded) { base.OnGUI(position, property, label); position.xMin += 6; //position.y += 1; } else { if (Event.current.type == EventType.Repaint) { header.Draw(position, false, false, false, false); position.xMin += 6; //position.y += 1; EditorGUI.LabelField(position, ReflectionHelper.GenerateGenericTypesAsString(property), styleLabel); } } GUIContent buttonContent = property.isExpanded ? m_IconToolbarMinus : m_IconToolbarPlus; Vector2 buttonIcon = GUIStyle.none.CalcSize(buttonContent); //Rect callbackRect = GUILayoutUtility.GetLastRect(); Rect callbackRect = position; Rect buttonIconPos = new Rect(callbackRect.xMax - buttonIcon.x - 8, callbackRect.y + 1, buttonIcon.x, buttonIcon.y); if (GUI.Button(buttonIconPos, buttonContent, GUIStyle.none)) { property.isExpanded = !property.isExpanded; } return(property.isExpanded); }
private static void DrawToggle(Toggle toggle) { SelectableDrawer.DrawSelectable(toggle); GUILayout.Space(10); using (new GUILayout.HorizontalScope()) { GUILayout.Label("Is On", GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH)); NitroxGUILayout.Separator(); toggle.isOn = NitroxGUILayout.BoolField(toggle.isOn); } using (new GUILayout.HorizontalScope()) { GUILayout.Label("Toggle Transition", NitroxGUILayout.DrawerLabel, GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH)); NitroxGUILayout.Separator(); toggle.toggleTransition = NitroxGUILayout.EnumPopup(toggle.toggleTransition); } using (new GUILayout.HorizontalScope()) { GUILayout.Label("Graphic", NitroxGUILayout.DrawerLabel, GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH)); NitroxGUILayout.Separator(); if (GUILayout.Button("Jump to", GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH))) { NitroxServiceLocator.Cache <SceneDebugger> .Value.UpdateSelectedObject(toggle.graphic.gameObject); } } using (new GUILayout.HorizontalScope()) { GUILayout.Label("Group", NitroxGUILayout.DrawerLabel, GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH)); NitroxGUILayout.Separator(); if (GUILayout.Button("Jump to", GUILayout.Width(NitroxGUILayout.DEFAULT_LABEL_WIDTH))) { NitroxServiceLocator.Cache <SceneDebugger> .Value.UpdateSelectedObject(toggle.group.gameObject); } } UnityEventDrawer.DrawUnityEventBool(toggle.onValueChanged, "OnClick()"); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { UnityEventDrawer eventDrawer = new UnityEventDrawer(); if (GetPersistentCallCount(property) == 0) { Rect r = new Rect(position.x, position.y, position.width, 18); GUI.BeginGroup(r); eventDrawer.OnGUI(new Rect(0, 0, r.width, r.height), property, label); GUI.EndGroup(); r = new Rect(position.x, position.y + 18, position.width, 15); GUI.BeginGroup(new Rect(r.x, r.y, r.width, r.height + 3)); eventDrawer.OnGUI(new Rect(0, -67, r.width, r.height), property, label); GUI.EndGroup(); } else { eventDrawer.OnGUI(position, property, new GUIContent(label)); } }
private bool isUnityEventsNullOrMissing(MonoBehaviour monoBehaviour, bool printError) { targetPropertiesNames.Clear(); FieldInfo[] fieldArray = monoBehaviour.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); for (int i = fieldArray.Length - 1; i >= 0; i--) { FieldInfo field = fieldArray[i]; if (field.FieldType == typeof(UnityEventBase) || field.FieldType.IsSubclassOf(typeof(UnityEventBase))) { targetPropertiesNames.Add(field.Name); } } if (targetPropertiesNames.Count > 0) { SerializedObject serializedMonoBehaviour = new SerializedObject(monoBehaviour); for (int i = targetPropertiesNames.Count - 1; i >= 0; i--) { string targetProperty = targetPropertiesNames[i]; SerializedProperty property = serializedMonoBehaviour.FindProperty(targetProperty); SerializedProperty propertyRelativeArrray = property.FindPropertyRelative("m_PersistentCalls.m_Calls"); for (int j = propertyRelativeArrray.arraySize - 1; j >= 0; j--) { SerializedProperty arrayElementAtIndex = propertyRelativeArrray.GetArrayElementAtIndex(j); SerializedProperty propertyTarget = arrayElementAtIndex.FindPropertyRelative("m_Target"); if (propertyTarget.objectReferenceValue == null) { if (printError) { appendErrorLine(monoBehaviour.GetType().Name + ": Event object reference is null"); } else { return(true); } } SerializedProperty propertyMethodName = arrayElementAtIndex.FindPropertyRelative("m_MethodName"); if (string.IsNullOrEmpty(propertyMethodName.stringValue)) { if (printError) { appendErrorLine(monoBehaviour.GetType().Name + ": Event handler function is not selected"); continue; } else { return(true); } } string argumentAssemblyTypeName = arrayElementAtIndex.FindPropertyRelative("m_Arguments").FindPropertyRelative("m_ObjectArgumentAssemblyTypeName").stringValue; System.Type argumentAssemblyType; if (!string.IsNullOrEmpty(argumentAssemblyTypeName)) { argumentAssemblyType = System.Type.GetType(argumentAssemblyTypeName, false) ?? typeof(UnityEngine.Object); } else { argumentAssemblyType = typeof(UnityEngine.Object); } UnityEventBase dummyEvent; System.Type propertyTypeName = System.Type.GetType(property.FindPropertyRelative("m_TypeName").stringValue, false); if (propertyTypeName == null) { dummyEvent = (UnityEventBase) new UnityEvent(); } else { dummyEvent = Activator.CreateInstance(propertyTypeName) as UnityEventBase; } if (!UnityEventDrawer.IsPersistantListenerValid(dummyEvent, propertyMethodName.stringValue, propertyTarget.objectReferenceValue, (PersistentListenerMode)arrayElementAtIndex.FindPropertyRelative("m_Mode").enumValueIndex, argumentAssemblyType)) { if (printError) { appendErrorLine(monoBehaviour.GetType().Name + ": Event handler function is missing"); } else { return(true); } } } } } return(false); }
private static void DrawButton(Button button) { SelectableDrawer.DrawSelectable(button); GUILayout.Space(10); UnityEventDrawer.DrawUnityEvent(button.onClick, "OnClick()"); }
public void TryDetectUnityEventIssues(RecordLocation location, string assetPath, GameObject target, Type componentType, string componentName, int orderIndex, SerializedProperty property) { if (!enabled) { return; } var callbacks = property.FindPropertyRelative("m_PersistentCalls.m_Calls"); if (callbacks == null || callbacks.isArray == false) { Maintainer.ConstructReportWarning("Couldn't find m_PersistentCalls in serialized UnityEvent!", IssuesFinder.ModuleName); return; } IssuesDetector.duplicateComponentDetector.ProcessProperty(callbacks); var callsCount = callbacks.arraySize; for (var i = 0; i < callsCount; i++) { var call = callbacks.GetArrayElementAtIndex(i); var callTarget = call.FindPropertyRelative("m_Target"); if (callTarget == null || callTarget.propertyType != SerializedPropertyType.ObjectReference) { Maintainer.ConstructReportWarning("Couldn't find m_Target in serialized UnityEvent's call!", IssuesFinder.ModuleName); return; } if (IsPropertyHasMissingReference(callTarget)) { AddIssue(location, assetPath, target, componentType, componentName, orderIndex, callTarget.propertyPath); return; } var callTargetObject = callTarget.objectReferenceValue; // no target set if (callTargetObject == null) { continue; } IssuesDetector.duplicateComponentDetector.ProcessProperty(callTarget); var methodName = call.FindPropertyRelative("m_MethodName"); if (methodName == null || methodName.propertyType != SerializedPropertyType.String) { Maintainer.ConstructReportWarning("Couldn't find m_MethodName in serialized UnityEvent's call!", IssuesFinder.ModuleName); return; } IssuesDetector.duplicateComponentDetector.ProcessProperty(methodName); var methodNameValue = methodName.stringValue; // no function set if (string.IsNullOrEmpty(methodNameValue)) { continue; } var arguments = call.FindPropertyRelative("m_Arguments"); if (arguments == null) { Maintainer.ConstructReportWarning("Couldn't find m_Arguments in serialized UnityEvent's call!", IssuesFinder.ModuleName); return; } var objectArgumentAssemblyTypeName = arguments.FindPropertyRelative("m_ObjectArgumentAssemblyTypeName"); if (objectArgumentAssemblyTypeName == null || objectArgumentAssemblyTypeName.propertyType != SerializedPropertyType.String) { Maintainer.ConstructReportWarning("Couldn't find m_ObjectArgumentAssemblyTypeName in m_Arguments!", IssuesFinder.ModuleName); return; } IssuesDetector.duplicateComponentDetector.ProcessProperty(objectArgumentAssemblyTypeName); var mode = call.FindPropertyRelative("m_Mode"); if (mode == null || mode.propertyType != SerializedPropertyType.Enum) { Maintainer.ConstructReportWarning("Couldn't find m_Mode in serialized UnityEvent's call!", IssuesFinder.ModuleName); return; } IssuesDetector.duplicateComponentDetector.ProcessProperty(mode); var modeValue = (PersistentListenerMode)mode.enumValueIndex; var dummyEvent = CSReflectionTools.GetDummyEvent(property); if (dummyEvent == null) { Maintainer.ConstructReportWarning("Couldn't get something from GetDummyEvent!", IssuesFinder.ModuleName); return; } var type = CSReflectionTools.objectType; var stringValue = objectArgumentAssemblyTypeName.stringValue; if (!string.IsNullOrEmpty(stringValue)) { type = Type.GetType(stringValue, false) ?? typeof(UnityEngine.Object); } if (!UnityEventDrawer.IsPersistantListenerValid(dummyEvent, methodNameValue, callTargetObject, modeValue, type)) { AddIssue(location, assetPath, target, componentType, componentName, orderIndex, methodName.propertyPath); return; } } }
protected virtual void DrawEvent(Rect rect, int index, bool isActive, bool isFocused) { var pListener = m_ListenersArray.GetArrayElementAtIndex(index); var contentRect = rect; contentRect.xMin -= 6; contentRect.xMax += 2; contentRect.y += 1; Rect[] subRects = GetRowRects(contentRect); Rect enabledRect = subRects[0]; Rect goRect = subRects[1]; Rect functionRect = subRects[2]; Rect argRect = subRects[3]; // find the current event target... var callState = pListener.FindPropertyRelative(kCallStatePath); var mode = pListener.FindPropertyRelative(kModePath); var arguments = pListener.FindPropertyRelative(kArgumentsPath); var listenerTarget = pListener.FindPropertyRelative(kInstancePath); var methodName = pListener.FindPropertyRelative(kMethodNamePath); Color c = GUI.backgroundColor; GUI.backgroundColor = Color.white; var callStateEnum = (UnityEventCallState)callState.enumValueIndex; var isEditorAndRuntime = callStateEnum == UnityEventCallState.EditorAndRuntime; var isRuntime = callStateEnum == UnityEventCallState.RuntimeOnly; var toggleRect = enabledRect; toggleRect.width = 16; if (isEditorAndRuntime || (isRuntime && Application.isPlaying)) { var markRect = new Rect(rect) { width = 2 }; markRect.x -= 20; EditorGUI.DrawRect(markRect, new Color(1, 0.7f, 0.4f, 1)); } var evt = Event.current; var color = GUI.color; var mousePos = evt.mousePosition; { var isHover = toggleRect.Contains(mousePos); if (isHover) { // Ooh, these beautiful 2-pixels of rounded edges.. GUI.DrawTexture(toggleRect, Texture2D.whiteTexture, ScaleMode.ScaleToFit, true, 1, new Color(1, 1, 1, 0.15f), Vector4.zero, 2); } } GUI.color = new Color(1, 1, 1, 0.75f); GUI.Box(toggleRect, DropdownIcon, EditorStyles.centeredGreyMiniLabel); GUI.color = color; GUI.color = new Color(0, 0, 0, 0); EditorGUI.PropertyField(toggleRect, callState, GUIContent.none); GUI.color = color; var isOff = callStateEnum == UnityEventCallState.Off; EditorGUI.BeginDisabledGroup(isOff); EditorGUI.BeginChangeCheck(); { GUI.Box(goRect, GUIContent.none); EditorGUI.PropertyField(goRect, listenerTarget, GUIContent.none); if (EditorGUI.EndChangeCheck()) { methodName.stringValue = null; } } SerializedProperty argument; var modeEnum = GetMode(mode); //only allow argument if we have a valid target / method if (listenerTarget.objectReferenceValue == null || string.IsNullOrEmpty(methodName.stringValue)) { modeEnum = PersistentListenerMode.Void; } switch (modeEnum) { case PersistentListenerMode.Float: argument = arguments.FindPropertyRelative(kFloatArgument); break; case PersistentListenerMode.Int: argument = arguments.FindPropertyRelative(kIntArgument); break; case PersistentListenerMode.Object: argument = arguments.FindPropertyRelative(kObjectArgument); break; case PersistentListenerMode.String: argument = arguments.FindPropertyRelative(kStringArgument); break; case PersistentListenerMode.Bool: argument = arguments.FindPropertyRelative(kBoolArgument); break; default: argument = arguments.FindPropertyRelative(kIntArgument); break; } var desiredArgTypeName = arguments.FindPropertyRelative(kObjectArgumentAssemblyTypeName).stringValue; var desiredType = typeof(Object); if (!string.IsNullOrEmpty(desiredArgTypeName)) { desiredType = Type.GetType(desiredArgTypeName, false) ?? typeof(Object); } argRect.xMin = goRect.xMax + Spacing; if (modeEnum == PersistentListenerMode.Object) { EditorGUI.BeginChangeCheck(); var result = EditorGUI.ObjectField(argRect, GUIContent.none, argument.objectReferenceValue, desiredType, true); if (EditorGUI.EndChangeCheck()) { argument.objectReferenceValue = result; } } else if (modeEnum != PersistentListenerMode.Void && modeEnum != PersistentListenerMode.EventDefined) { EditorGUI.PropertyField(argRect, argument, GUIContent.none); } using (new EditorGUI.DisabledScope(listenerTarget.objectReferenceValue == null)) { EditorGUI.BeginProperty(functionRect, GUIContent.none, methodName); { GUIContent buttonContent; if (EditorGUI.showMixedValue) { buttonContent = MixedValueContent; } else { var buttonLabel = new StringBuilder(); if (listenerTarget.objectReferenceValue == null || string.IsNullOrEmpty(methodName.stringValue)) { buttonLabel.Append(kNoFunctionString); } else if (!UnityEventDrawer.IsPersistantListenerValid(m_DummyEvent, methodName.stringValue, listenerTarget.objectReferenceValue, GetMode(mode), desiredType)) { var instanceString = "UnknownComponent"; var instance = listenerTarget.objectReferenceValue; if (instance != null) { instanceString = instance.GetType().Name; } buttonLabel.Append(string.Format("<Missing {0}.{1}>", instanceString, methodName.stringValue)); } else { buttonLabel.Append(listenerTarget.objectReferenceValue.GetType().Name); if (!string.IsNullOrEmpty(methodName.stringValue)) { buttonLabel.Append("."); if (methodName.stringValue.StartsWith("set_")) { buttonLabel.Append(methodName.stringValue.Substring(4)); } else { buttonLabel.Append(methodName.stringValue); } } } TempContent.text = buttonLabel.ToString(); buttonContent = TempContent; } if (GUI.Button(functionRect, buttonContent, EditorStyles.popup)) { var popup = BuildPopupList.Invoke(null, new object[] { listenerTarget.objectReferenceValue, m_DummyEvent, pListener }) as GenericMenu; popup.DropDown(functionRect); } } EditorGUI.EndProperty(); } EditorGUI.EndDisabledGroup(); GUI.backgroundColor = c; }