public static void GetWindow(System.Type type, CustomObjectPickerAttribute attr, System.Action <Object> callback) { GetWindow <CustomObjectPickerEditorWindow>(false, "Select Object", true); _callback = callback; FilterAssets(type, attr); }
private static void ObjectField(Rect position, Rect dropRect, GUIContent fieldName, int id, Object obj, Type reqObjType, CustomObjectPickerAttribute attr, Action <Object> callback) { Event current = Event.current; EventType eventType = current.type; if (!GUI.enabled && Event.current.rawType == EventType.MouseDown) { eventType = Event.current.rawType; } if (fieldName != null && string.IsNullOrEmpty(fieldName.text) == false) { var labelPos = position; labelPos.width = EditorGUIUtility.labelWidth; EditorGUI.PrefixLabel(labelPos, fieldName); position.x += labelPos.width; position.width -= labelPos.width; } if (Event.current.type == EventType.Repaint) { EditorGUIUtility.SetIconSize(new Vector2(12f, 12f)); var gUIContent = EditorGUIUtility.ObjectContent(obj, reqObjType); Rect position2 = EditorStyles.objectField.margin.Remove(new Rect(position.xMax - 19f, position.y, 19f, position.height)); //GUIStyle style = new GUIStyle(); //style.Draw(position, gUIContent, id, DragAndDrop.activeControlID == id, position.Contains(Event.current.mousePosition)); EditorStyles.objectField.Draw(position, GUIContent.none, id, DragAndDrop.activeControlID == id, position.Contains(Event.current.mousePosition)); EditorStyles.objectField.Draw(position2, new GUIContent(), id, DragAndDrop.activeControlID == id, position2.Contains(Event.current.mousePosition)); EditorGUI.LabelField(position, gUIContent, EditorStyles.label); } //EditorGUI.LabelField(position, ObjectNames.GetDragAndDropTitle(obj), EditorStyles.objectField); position.width -= 32; if (Event.current.type == EventType.MouseDown) { if (position.Contains(Event.current.mousePosition) && obj != null) { Selection.objects = new[] { obj }; EditorGUIUtility.PingObject(obj); Event.current.Use(); GUIUtility.ExitGUI(); } position.x += position.width; position.width = 32; if (position.Contains(Event.current.mousePosition)) { //Could be awesome! but requires a bit more work see: https://answers.unity.com/questions/554012/how-do-i-use-editorguiutilityshowobjectpicker-c.html //EditorGUIUtility.ShowObjectPicker<Object>(obj, true, "t:" + nameof(reqObjType), EditorGUIUtility.GetControlID(FocusType.Passive) + 100); CustomObjectPickerEditorWindow.GetWindow(reqObjType, attr, (val) => { if (callback != null) { callback(val); } GUI.changed = true; }); } } EventType eventType2 = eventType; switch (eventType2) { case EventType.KeyUp: case EventType.ScrollWheel: case EventType.Layout: case EventType.Ignore: case EventType.Used: case EventType.ValidateCommand: case EventType.Repaint: case EventType.ExecuteCommand: break; case EventType.DragUpdated: case EventType.DragPerform: if (dropRect.Contains(Event.current.mousePosition) && GUI.enabled) { Object[] objectReferences = DragAndDrop.objectReferences; var obj2 = objectReferences.FirstOrDefault(); if (obj2 != null) { DragAndDrop.visualMode = DragAndDropVisualMode.Generic; if (eventType == EventType.DragPerform && ValidateObject(obj2, reqObjType, attr, true)) { obj = obj2; GUI.changed = true; Type objType = obj.GetType(); if (GameObjectType.IsAssignableFrom(objType)) { var objAsGameObject = obj as GameObject; if (GameObjectType.IsAssignableFrom(reqObjType)) { callback(obj); } else if (ComponentType.IsAssignableFrom(reqObjType)) { Object[] objs = (obj as GameObject).GetComponents(reqObjType); foreach (var @object in objs) { bool success = true; foreach (var restriction in attr.typeRestrictions) { if (!restriction.IsAssignableFrom(@object.GetType())) { success = false; } } if (success) { callback(@object); } } } } else { callback(obj); } DragAndDrop.AcceptDrag(); DragAndDrop.activeControlID = 0; } else { DragAndDrop.activeControlID = id; } Event.current.Use(); } } break; case EventType.DragExited: if (GUI.enabled) { HandleUtility.Repaint(); } break; } }
private static void RenderObjectPicker(Rect rect, string fieldName, SerializedProperty prop, Type reqObjType, CustomObjectPickerAttribute attr) { GUIContent content = GetContentFromObject(prop.objectReferenceValue, reqObjType); ObjectField(rect, rect, new GUIContent(fieldName), 1, prop.objectReferenceValue, reqObjType, attr, (val) => { prop.objectReferenceValue = val; prop.serializedObject.ApplyModifiedProperties(); prop.serializedObject.Update(); }); }
private static bool ValidateObject(Object obj, Type reqObjType, CustomObjectPickerAttribute attr, bool includeGOComponents = false) { if (obj == null) { return(false); } Type objType = obj.GetType(); if (GameObjectType.IsAssignableFrom(reqObjType)) { if (GameObjectType.IsAssignableFrom(objType)) { foreach (var restriction in attr.typeRestrictions) { if ((obj as GameObject).GetComponent(restriction) == null) { return(false); } } return(true); } } else if (ComponentType.IsAssignableFrom(reqObjType)) { if (includeGOComponents && GameObjectType.IsAssignableFrom(objType)) { Object[] objs = (obj as GameObject).GetComponents(reqObjType); foreach (var @object in objs) { bool success = true; foreach (var restriction in attr.typeRestrictions) { if (!restriction.IsAssignableFrom(@object.GetType())) { success = false; } } if (success) { return(true); } } return(false); } else { if (ComponentType.IsAssignableFrom(objType)) { foreach (var restriction in attr.typeRestrictions) { if (!restriction.IsAssignableFrom(objType)) { return(false); } } return(true); } } } else if (ScriptableObjectType.IsAssignableFrom(reqObjType)) { if (ScriptableObjectType.IsAssignableFrom(objType)) { foreach (var restriction in attr.typeRestrictions) { if (!restriction.IsAssignableFrom(objType)) { return(false); } } return(true); } } return(false); }
private static void FilterAssets(System.Type type, CustomObjectPickerAttribute attr) { if (!typeof(Object).IsAssignableFrom(type)) { _allMatchingObjects = Enumerable.Empty <Object>(); throw new System.Exception("Field should be of a sub-type of UnityEngine.Object!"); } _allMatchingObjects = Enumerable.Empty <Object>(); IEnumerable <Object> foundObj = Enumerable.Empty <Object>(); if (type.IsAssignableFrom(typeof(GameObject)) || typeof(GameObject).IsAssignableFrom(type)) { foundObj = Resources.FindObjectsOfTypeAll(typeof(GameObject)); if (attr.resultObjectType != ResultObjectType.SceneOrAsset) { if (attr.resultObjectType == ResultObjectType.Scene) { foundObj = foundObj.Where((t) => t != null && !IsAPrefab <GameObject>(t)); } if (attr.resultObjectType == ResultObjectType.Asset) { foundObj = foundObj.Where((t) => t != null && IsAPrefab <GameObject>(t)); } } // if we're dealing with GameObject references, then we'll restrict outrselves to any // GameObject with components attached that possess all type limitations collectively foreach (var restrictionType in attr.typeRestrictions) { foundObj = foundObj.Where(t => (t as GameObject).GetComponent(restrictionType) != null).ToList(); } _allMatchingObjects = _allMatchingObjects.Union(foundObj); } if (type.IsAssignableFrom(typeof(Component)) || typeof(Component).IsAssignableFrom(type)) { foundObj = Resources.FindObjectsOfTypeAll(typeof(Component)); if (attr.resultObjectType != ResultObjectType.SceneOrAsset) { if (attr.resultObjectType == ResultObjectType.Scene) { foundObj = foundObj.Where(t => t != null && !IsAPrefab <Component>(t)); } if (attr.resultObjectType == ResultObjectType.Asset) { foundObj = foundObj.Where(t => t != null && IsAPrefab <Component>(t)); } } // if we're dealing with components, then we limit ourselves to components that derive // or implement all restriction type foreach (var restrictionType in attr.typeRestrictions) { foundObj = foundObj.Where(t => restrictionType.IsAssignableFrom(t.GetType())); } _allMatchingObjects = _allMatchingObjects.Union(foundObj); } if (type.IsAssignableFrom(typeof(ScriptableObject)) || typeof(ScriptableObject).IsAssignableFrom(type)) { foundObj = Resources.FindObjectsOfTypeAll(typeof(ScriptableObject)); // ScriptableObjects are assets only, so we can skip the asset/scene object check foreach (var restrictionType in attr.typeRestrictions) { foundObj = foundObj.Where(t => restrictionType.IsAssignableFrom(t.GetType())); } _allMatchingObjects = _allMatchingObjects.Union(foundObj); } foundObj = null; }