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 FilterAssets(System.Type type, CustomObjectPickerAttribute attr) { _allMatchingObjects = Resources.FindObjectsOfTypeAll(type); if (typeof(GameObject).IsAssignableFrom(type)) { if (attr.resultObjectType != CustomObjectPickerAttribute.ResultObjectType.SceneOrAsset) { if (attr.resultObjectType == CustomObjectPickerAttribute.ResultObjectType.Scene) { _allMatchingObjects = _allMatchingObjects.Where(t => PrefabUtility.GetPrefabType(t as GameObject) != PrefabType.Prefab); } if (attr.resultObjectType == CustomObjectPickerAttribute.ResultObjectType.Asset) { _allMatchingObjects = _allMatchingObjects.Where(t => PrefabUtility.GetPrefabType(t as GameObject) == PrefabType.Prefab); } } // 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) { _allMatchingObjects = _allMatchingObjects.Where(t => (t as GameObject).GetComponent(restrictionType) != null).ToList(); } } else if (typeof(Component).IsAssignableFrom(type)) { if (attr.resultObjectType != CustomObjectPickerAttribute.ResultObjectType.SceneOrAsset) { if (attr.resultObjectType == CustomObjectPickerAttribute.ResultObjectType.Scene) { _allMatchingObjects = _allMatchingObjects.Where(t => PrefabUtility.GetPrefabType((t as Component).gameObject) != PrefabType.Prefab); } if (attr.resultObjectType == CustomObjectPickerAttribute.ResultObjectType.Asset) { _allMatchingObjects = _allMatchingObjects.Where(t => PrefabUtility.GetPrefabType((t as Component).gameObject) == PrefabType.Prefab); } } // 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) { _allMatchingObjects = _allMatchingObjects.Where(t => restrictionType.IsAssignableFrom(t.GetType())); } } else if (typeof(ScriptableObject).IsAssignableFrom(type)) { // ScriptableObjects are assets only, so we can skip the asset/scene object check foreach (var restrictionType in attr.typeRestrictions) { _allMatchingObjects = _allMatchingObjects.Where(t => restrictionType.IsAssignableFrom(t.GetType())); } } }
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 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; } EditorGUI.LabelField(position, obj ? $"{obj.name} [{obj.GetType().Name}]" : $"None ({attr.typeRestrictions.JoinString(", ", a => a.GetSimpleAliasName())})", EditorStyles.objectField); position.width -= 32; if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseUp) { 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)) { 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; } }