internal static void AddSetToValueOfTargetMenuItems(GenericMenu menu, SerializedProperty property, TargetChoiceHandler.TargetChoiceMenuFunction func) { SerializedProperty property2 = property.serializedObject.FindProperty(property.propertyPath); UnityEngine.Object[] targetObjects = property.serializedObject.targetObjects; List<string> list = new List<string>(); UnityEngine.Object[] array = targetObjects; for (int i = 0; i < array.Length; i++) { UnityEngine.Object @object = array[i]; string text = "Set to Value of " + @object.name; if (list.Contains(text)) { int num = 1; while (true) { text = string.Concat(new object[] { "Set to Value of ", @object.name, " (", num, ")" }); if (!list.Contains(text)) { break; } num++; } } list.Add(text); menu.AddItem(EditorGUIUtility.TextContent(text), false, new GenericMenu.MenuFunction2(TargetChoiceHandler.TargetChoiceForwardFunction), new PropertyAndTargetHandler(property2, @object, func)); } }
internal static void TargetChoiceField(Rect position, SerializedProperty property, GUIContent label, TargetChoiceHandler.TargetChoiceMenuFunction func) { EditorGUI.BeginProperty(position, label, property); position = EditorGUI.PrefixLabel(position, 0, label); EditorGUI.BeginHandleMixedValueContentColor(); if (GUI.Button(position, EditorGUI.mixedValueContent, EditorStyles.popup)) { GenericMenu menu = new GenericMenu(); TargetChoiceHandler.AddSetToValueOfTargetMenuItems(menu, property, func); menu.DropDown(position); } EditorGUI.EndHandleMixedValueContentColor(); EditorGUI.EndProperty(); }
internal static void AddSetToValueOfTargetMenuItems(GenericMenu menu, SerializedProperty property, TargetChoiceHandler.TargetChoiceMenuFunction func) { SerializedProperty property1 = property.serializedObject.FindProperty(property.propertyPath); Object[] targetObjects = property.serializedObject.targetObjects; List<string> stringList = new List<string>(); foreach (Object target in targetObjects) { string textAndTooltip = "Set to Value of " + target.name; if (stringList.Contains(textAndTooltip)) { int num = 1; while (true) { textAndTooltip = "Set to Value of " + target.name + " (" + (object) num + ")"; if (stringList.Contains(textAndTooltip)) ++num; else break; } } stringList.Add(textAndTooltip); menu.AddItem(EditorGUIUtility.TextContent(textAndTooltip), false, new GenericMenu.MenuFunction2(TargetChoiceHandler.TargetChoiceForwardFunction), (object) new PropertyAndTargetHandler(property1, target, func)); } }
static Object DoObjectField(Rect position, Rect dropRect, int id, Object obj, Object objBeingEdited, System.Type objType, System.Type additionalType, SerializedProperty property, ObjectFieldValidator validator, bool allowSceneObjects, GUIStyle style, GUIStyle buttonStyle) { if (validator == null) { validator = ValidateObjectFieldAssignment; } if (property != null) { obj = property.objectReferenceValue; } Event evt = Event.current; EventType eventType = evt.type; // special case test, so we continue to ping/select objects with the object field disabled if (!GUI.enabled && GUIClip.enabled && (Event.current.rawType == EventType.MouseDown)) { eventType = Event.current.rawType; } bool hasThumbnail = EditorGUIUtility.HasObjectThumbnail(objType); // Determine visual type ObjectFieldVisualType visualType = ObjectFieldVisualType.IconAndText; if (hasThumbnail && position.height <= kObjectFieldMiniThumbnailHeight && position.width <= kObjectFieldMiniThumbnailWidth) { visualType = ObjectFieldVisualType.MiniPreview; } else if (hasThumbnail && position.height > kSingleLineHeight) { visualType = ObjectFieldVisualType.LargePreview; } Vector2 oldIconSize = EditorGUIUtility.GetIconSize(); if (visualType == ObjectFieldVisualType.IconAndText) { EditorGUIUtility.SetIconSize(new Vector2(12, 12)); // Have to be this small to fit inside a single line height ObjectField } else if (visualType == ObjectFieldVisualType.LargePreview) { EditorGUIUtility.SetIconSize(new Vector2(64, 64)); } if ((eventType == EventType.MouseDown && Event.current.button == 1 || (eventType == EventType.ContextClick && visualType == ObjectFieldVisualType.IconAndText)) && position.Contains(Event.current.mousePosition)) { var actualObject = property != null ? property.objectReferenceValue : obj; var contextMenu = new GenericMenu(); if (FillPropertyContextMenu(property, null, contextMenu) != null) { contextMenu.AddSeparator(""); } contextMenu.AddItem(GUIContent.Temp("Properties..."), false, () => PropertyEditor.OpenPropertyEditor(actualObject)); contextMenu.DropDown(position); Event.current.Use(); } switch (eventType) { case EventType.DragExited: if (GUI.enabled) { HandleUtility.Repaint(); } break; case EventType.DragUpdated: case EventType.DragPerform: if (eventType == EventType.DragPerform) { string errorString; if (!ValidDroppedObject(DragAndDrop.objectReferences, objType, out errorString)) { Object reference = DragAndDrop.objectReferences[0]; EditorUtility.DisplayDialog("Can't assign script", errorString, "OK"); break; } } if (dropRect.Contains(Event.current.mousePosition) && GUI.enabled) { Object[] references = DragAndDrop.objectReferences; Object validatedObject = validator(references, objType, property, ObjectFieldValidatorOptions.None); if (validatedObject != null) { // If scene objects are not allowed and object is a scene object then clear if (!allowSceneObjects && !EditorUtility.IsPersistent(validatedObject)) { validatedObject = null; } } if (validatedObject != null) { DragAndDrop.visualMode = DragAndDropVisualMode.Generic; if (eventType == EventType.DragPerform) { if (property != null) { property.objectReferenceValue = validatedObject; } else { obj = validatedObject; } GUI.changed = true; DragAndDrop.AcceptDrag(); DragAndDrop.activeControlID = 0; } else { DragAndDrop.activeControlID = id; } Event.current.Use(); } } break; case EventType.MouseDown: if (position.Contains(Event.current.mousePosition) && Event.current.button == 0) { // Get button rect for Object Selector Rect buttonRect = GetButtonRect(visualType, position); EditorGUIUtility.editingTextField = false; if (buttonRect.Contains(Event.current.mousePosition)) { if (GUI.enabled) { GUIUtility.keyboardControl = id; var types = additionalType == null ? new Type[] { objType } : new Type[] { objType, additionalType }; if (property != null) { ObjectSelector.get.Show(types, property, allowSceneObjects); } else { ObjectSelector.get.Show(obj, types, objBeingEdited, allowSceneObjects); } ObjectSelector.get.objectSelectorID = id; evt.Use(); GUIUtility.ExitGUI(); } } else { Object actualTargetObject = property != null ? property.objectReferenceValue : obj; Component com = actualTargetObject as Component; if (com) { actualTargetObject = com.gameObject; } if (showMixedValue) { actualTargetObject = null; } // One click shows where the referenced object is, or pops up a preview if (Event.current.clickCount == 1) { GUIUtility.keyboardControl = id; PingObjectOrShowPreviewOnClick(actualTargetObject, position); var selectedMaterial = actualTargetObject as Material; if (selectedMaterial != null) { PingObjectInSceneViewOnClick(selectedMaterial); } evt.Use(); } // Double click opens the asset in external app or changes selection to referenced object else if (Event.current.clickCount == 2) { if (actualTargetObject) { AssetDatabase.OpenAsset(actualTargetObject); evt.Use(); GUIUtility.ExitGUI(); } } } } break; case EventType.ExecuteCommand: string commandName = evt.commandName; if (commandName == ObjectSelector.ObjectSelectorUpdatedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && (property == null || !property.isScript)) { return(AssignSelectedObject(property, validator, objType, evt)); } else if (commandName == ObjectSelector.ObjectSelectorClosedCommand && ObjectSelector.get.objectSelectorID == id && GUIUtility.keyboardControl == id && property != null && property.isScript) { if (ObjectSelector.get.GetInstanceID() == 0) { // User canceled object selection; don't apply evt.Use(); break; } return(AssignSelectedObject(property, validator, objType, evt)); } else if ((evt.commandName == EventCommandNames.Delete || evt.commandName == EventCommandNames.SoftDelete) && GUIUtility.keyboardControl == id) { if (property != null) { property.objectReferenceValue = null; } else { obj = null; } GUI.changed = true; evt.Use(); } break; case EventType.ValidateCommand: if ((evt.commandName == EventCommandNames.Delete || evt.commandName == EventCommandNames.SoftDelete) && GUIUtility.keyboardControl == id) { evt.Use(); } break; case EventType.KeyDown: if (GUIUtility.keyboardControl == id) { if (evt.keyCode == KeyCode.Backspace || (evt.keyCode == KeyCode.Delete && (evt.modifiers & EventModifiers.Shift) == 0)) { if (property != null) { if (property.propertyPath.EndsWith("]")) { var parentArrayPropertyPath = property.propertyPath.Substring(0, property.propertyPath.LastIndexOf(".Array.data[", StringComparison.Ordinal)); var parentArrayProperty = property.serializedObject.FindProperty(parentArrayPropertyPath); bool isReorderableList = PropertyHandler.s_reorderableLists.ContainsKey(ReorderableListWrapper.GetPropertyIdentifier(parentArrayProperty)); // If it's an element of an non-orderable array, remove that element from the array if (!isReorderableList) { TargetChoiceHandler.DeleteArrayElement(property); } else { property.objectReferenceValue = null; } } else { property.objectReferenceValue = null; } } else { obj = null; } GUI.changed = true; evt.Use(); } // Apparently we have to check for the character being space instead of the keyCode, // otherwise the Inspector will maximize upon pressing space. if (evt.MainActionKeyForControl(id)) { var types = additionalType == null ? new Type[] { objType } : new Type[] { objType, additionalType }; if (property != null) { ObjectSelector.get.Show(types, property, allowSceneObjects); } else { ObjectSelector.get.Show(obj, types, objBeingEdited, allowSceneObjects); } ObjectSelector.get.objectSelectorID = id; evt.Use(); GUIUtility.ExitGUI(); } } break; case EventType.Repaint: GUIContent temp; if (showMixedValue) { temp = s_MixedValueContent; } else { // If obj or objType are both null, we have to rely on // property.objectReferenceStringValue to display None/Missing and the // correct type. But if not, EditorGUIUtility.ObjectContent is more reliable. // It can take a more specific object type specified as argument into account, // and it gets the icon at the same time. if (obj == null && objType == null && property != null) { temp = EditorGUIUtility.TempContent(property.objectReferenceStringValue); } else { // In order for ObjectContext to be able to distinguish between None/Missing, // we need to supply an instanceID. For some reason, getting the instanceID // from property.objectReferenceValue is not reliable, so we have to // explicitly check property.objectReferenceInstanceIDValue if a property exists. if (property != null) { temp = EditorGUIUtility.ObjectContent(obj, objType, property.objectReferenceInstanceIDValue); } else { temp = EditorGUIUtility.ObjectContent(obj, objType); } } if (property != null) { if (obj != null) { Object[] references = { obj }; if (EditorSceneManager.preventCrossSceneReferences && CheckForCrossSceneReferencing(obj, property.serializedObject.targetObject)) { if (!EditorApplication.isPlaying) { temp = s_SceneMismatch; } else { temp.text = temp.text + string.Format(" ({0})", GetGameObjectFromObject(obj).scene.name); } } else if (validator(references, objType, property, ObjectFieldValidatorOptions.ExactObjectTypeValidation) == null) { temp = s_TypeMismatch; } } } } switch (visualType) { case ObjectFieldVisualType.IconAndText: BeginHandleMixedValueContentColor(); style.Draw(position, temp, id, DragAndDrop.activeControlID == id, position.Contains(Event.current.mousePosition)); Rect buttonRect = buttonStyle.margin.Remove(GetButtonRect(visualType, position)); buttonStyle.Draw(buttonRect, GUIContent.none, id, DragAndDrop.activeControlID == id, buttonRect.Contains(Event.current.mousePosition)); EndHandleMixedValueContentColor(); break; case ObjectFieldVisualType.LargePreview: DrawObjectFieldLargeThumb(position, id, obj, temp); break; case ObjectFieldVisualType.MiniPreview: DrawObjectFieldMiniThumb(position, id, obj, temp); break; default: throw new ArgumentOutOfRangeException(); } break; } EditorGUIUtility.SetIconSize(oldIconSize); return(obj); }
public PropertyAndTargetHandler(SerializedProperty property, Object target, TargetChoiceHandler.TargetChoiceMenuFunction function) { this.property = property; this.target = target; this.function = function; }
internal static void TargetChoiceField(SerializedProperty property, GUIContent label, TargetChoiceHandler.TargetChoiceMenuFunction func, params GUILayoutOption[] options) { Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.fieldWidth, EditorGUILayout.kLabelFloatMaxW, 16f, 16f, EditorStyles.popup, options); EditorGUI.TargetChoiceField(rect, property, label, func); }