void FolderBrowsing() { // We are not concerned with assets being added multiple times as we only show the contents // of each selected folder. This is an issue when searching recursively into child folders. List <FilterResult> list = new List <FilterResult>(); HierarchyProperty property; foreach (string folderPath in m_SearchFilter.folders) { if (folderPath == PackageManager.Folders.GetPackagesPath()) { var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(m_SearchFilter.skipHidden); foreach (var package in packages) { var packageFolderInstanceId = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(package.assetPath); property = new HierarchyProperty(package.assetPath); if (property.Find(packageFolderInstanceId, null)) { FilterResult result = new FilterResult(); CopyPropertyData(ref result, property); result.name = !string.IsNullOrEmpty(package.displayName) ? package.displayName : package.name; list.Add(result); } } continue; } if (m_SearchFilter.skipHidden && !PackageManagerUtilityInternal.IsPathInVisiblePackage(folderPath)) { continue; } int folderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(folderPath); property = new HierarchyProperty(folderPath); property.SetSearchFilter(m_SearchFilter); int folderDepth = property.depth; int[] expanded = { folderInstanceID }; while (property.Next(expanded)) { if (property.depth <= folderDepth) { break; // current property is outside folder } FilterResult result = new FilterResult(); CopyPropertyData(ref result, property); list.Add(result); // Fetch sub assets by expanding the main asset (ignore folders) if (property.hasChildren && !property.isFolder) { System.Array.Resize(ref expanded, expanded.Length + 1); expanded[expanded.Length - 1] = property.instanceID; } } } m_Results = list.ToArray(); }
private static IEnumerator <T> FindInFolders <T>(SearchFilter searchFilter, Func <HierarchyProperty, T> selector) { var folders = new List <string>(); folders.AddRange(searchFilter.folders); if (folders.Remove(PackageManager.Folders.GetPackagesPath())) { var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(searchFilter.skipHidden); foreach (var package in packages) { if (!folders.Contains(package.assetPath)) { folders.Add(package.assetPath); } } } foreach (var folderPath in folders) { var sanitizedFolderPath = folderPath.ConvertSeparatorsToUnity().TrimTrailingSlashes(); var folderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(sanitizedFolderPath); var rootPath = "Assets"; // Find the right rootPath if folderPath is part of a package var packageInfo = PackageManager.PackageInfo.FindForAssetPath(sanitizedFolderPath); if (packageInfo != null) { rootPath = packageInfo.assetPath; if (searchFilter.skipHidden && !PackageManagerUtilityInternal.IsPathInVisiblePackage(rootPath)) { continue; } } // Set empty filter to ensure we search all assets to find folder var property = new HierarchyProperty(rootPath); property.SetSearchFilter(new SearchFilter()); if (property.Find(folderInstanceID, null)) { // Set filter after we found the folder property.SetSearchFilter(searchFilter); int folderDepth = property.depth; int[] expanded = null; // enter all children of folder while (property.NextWithDepthCheck(expanded, folderDepth + 1)) { yield return(selector(property)); } } else { Debug.LogWarning("AssetDatabase.FindAssets: Folder not found: '" + sanitizedFolderPath + "'"); } } }
internal void Show(UnityObject obj, Type[] requiredTypes, UnityObject objectBeingEdited, bool allowSceneObjects, List <int> allowedInstanceIDs = null, Action <UnityObject> onObjectSelectorClosed = null, Action <UnityObject> onObjectSelectedUpdated = null) { m_ObjectSelectorReceiver = null; m_AllowSceneObjects = allowSceneObjects; m_IsShowingAssets = true; m_SkipHiddenPackages = true; m_AllowedIDs = allowedInstanceIDs; m_ObjectBeingEdited = objectBeingEdited; m_LastSelectedInstanceId = obj?.GetInstanceID() ?? 0; m_SelectionCancelled = false; m_OnObjectSelectorClosed = onObjectSelectorClosed; m_OnObjectSelectorUpdated = onObjectSelectedUpdated; // Do not allow to show scene objects if the object being edited is persistent if (m_ObjectBeingEdited != null && EditorUtility.IsPersistent(m_ObjectBeingEdited)) { m_AllowSceneObjects = false; } // Set which tab should be visible at startup if (m_AllowSceneObjects) { if (obj != null) { if (typeof(Component).IsAssignableFrom(obj.GetType())) { obj = ((Component)obj).gameObject; } // Set the right tab visible (so we can see our selection) m_IsShowingAssets = EditorUtility.IsPersistent(obj); } else { foreach (var requiredType in requiredTypes) { m_IsShowingAssets &= (requiredType != typeof(GameObject) && !typeof(Component).IsAssignableFrom(requiredType)); } } } else { m_IsShowingAssets = true; } // Set member variables m_DelegateView = GUIView.current; // type filter requires unqualified names for built-in types, but will prioritize them over user types, so ensure user types are namespace-qualified if (m_RequiredTypes == null) { m_RequiredTypes = new string[requiredTypes.Length]; } for (int i = 0; i < requiredTypes.Length; i++) { if (requiredTypes[i] != null) { m_RequiredTypes[i] = typeof(ScriptableObject).IsAssignableFrom(requiredTypes[i]) || typeof(MonoBehaviour).IsAssignableFrom(requiredTypes[i]) ? requiredTypes[i].FullName : requiredTypes[i].Name; } } m_SearchFilter = ""; m_OriginalSelection = obj; m_ModalUndoGroup = Undo.GetCurrentGroup(); // Show custom selector if available if (ObjectSelectorSearch.HasEngineOverride()) { m_SearchSessionHandler.BeginSession(() => { return(new SearchService.ObjectSelectorSearchContext { currentObject = obj, editedObjects = m_EditedProperty != null ? m_EditedProperty.serializedObject.targetObjects : new[] { objectBeingEdited }, requiredTypes = requiredTypes, requiredTypeNames = m_RequiredTypes, allowedInstanceIds = allowedInstanceIDs, visibleObjects = allowSceneObjects ? SearchService.VisibleObjects.All : SearchService.VisibleObjects.Assets, }); }); Action <UnityObject> onSelectionChanged = selectedObj => { m_LastSelectedInstanceId = selectedObj == null ? 0 : selectedObj.GetInstanceID(); NotifySelectionChanged(false); }; Action <UnityObject, bool> onSelectorClosed = (selectedObj, canceled) => { m_SearchSessionHandler.EndSession(); if (canceled) { // Undo changes we have done in the ObjectSelector Undo.RevertAllDownToGroup(m_ModalUndoGroup); m_LastSelectedInstanceId = 0; m_SelectionCancelled = true; } else { m_LastSelectedInstanceId = selectedObj == null ? 0 : selectedObj.GetInstanceID(); NotifySelectionChanged(false); } m_EditedProperty = null; NotifySelectorClosed(false); }; if (m_SearchSessionHandler.SelectObject(onSelectorClosed, onSelectionChanged)) { return; } else { m_SearchSessionHandler.EndSession(); } } // Freeze to prevent flicker on OSX. // Screen will be updated again when calling // SetFreezeDisplay(false) further down. ContainerWindow.SetFreezeDisplay(true); var shouldRepositionWindow = m_Parent != null; ShowWithMode(ShowMode.AuxWindow); string text = "Select " + (requiredTypes[0] == null ? m_RequiredTypes[0] : requiredTypes[0].Name); for (int i = 1; i < requiredTypes.Length; i++) { text += (i == requiredTypes.Length - 1 ? " or " : ", ") + (requiredTypes[i] == null ? m_RequiredTypes[i] : requiredTypes[i].Name); } titleContent = EditorGUIUtility.TrTextContent(text); // Deal with window size if (shouldRepositionWindow) { m_Parent.window.LoadInCurrentMousePosition(); m_Parent.window.FitWindowToScreen(true); } Rect p = m_Parent == null ? new Rect(0, 0, 1, 1) : m_Parent.window.position; p.width = EditorPrefs.GetFloat("ObjectSelectorWidth", 200); p.height = EditorPrefs.GetFloat("ObjectSelectorHeight", 390); position = p; minSize = new Vector2(kMinWidth, kMinTopSize + kPreviewExpandedAreaHeight + 2 * kPreviewMargin); maxSize = new Vector2(10000, 10000); SetupPreview(); // Focus Focus(); ContainerWindow.SetFreezeDisplay(false); m_FocusSearchFilter = true; // Add after unfreezing display because AuxWindowManager.cpp assumes that aux windows are added after we get 'got/lost'- focus calls. if (m_Parent != null) { m_Parent.AddToAuxWindowList(); } // Initial selection int initialSelection = obj != null?obj.GetInstanceID() : 0; if (initialSelection != 0) { var assetPath = AssetDatabase.GetAssetPath(initialSelection); if (m_SkipHiddenPackages && !PackageManagerUtilityInternal.IsPathInVisiblePackage(assetPath)) { m_SkipHiddenPackages = false; } } if (m_RequiredTypes.All(t => ShouldTreeViewBeUsed(t))) { m_ObjectTreeWithSearch.Init(position, this, CreateAndSetTreeView, TreeViewSelection, ItemWasDoubleClicked, initialSelection, 0); } else { // To frame the selected item we need to wait to initialize the search until our window has been setup InitIfNeeded(); m_ListArea.InitSelection(new[] { initialSelection }); if (initialSelection != 0) { m_ListArea.Frame(initialSelection, true, false); } } }
internal void Show(UnityObject obj, Type requiredType, SerializedProperty property, bool allowSceneObjects, List <int> allowedInstanceIDs, Action <UnityObject> onObjectSelectorClosed, Action <UnityObject> onObjectSelectedUpdated) { m_ObjectSelectorReceiver = null; m_AllowSceneObjects = allowSceneObjects; m_IsShowingAssets = true; m_SkipHiddenPackages = true; m_AllowedIDs = allowedInstanceIDs; m_OnObjectSelectorClosed = onObjectSelectorClosed; m_OnObjectSelectorUpdated = onObjectSelectedUpdated; if (property != null) { if (requiredType == null) { ScriptAttributeUtility.GetFieldInfoFromProperty(property, out requiredType); // case 951876: built-in types do not actually have reflectable fields, so their object types must be extracted from the type string // this works because built-in types will only ever have serialized references to other built-in types, which this window's filter expects as unqualified names if (requiredType == null) { m_RequiredType = s_MatchPPtrTypeName.Match(property.type).Groups[1].Value; } } obj = property.objectReferenceValue; m_ObjectBeingEdited = property.serializedObject.targetObject; // Do not allow to show scene objects if the object being edited is persistent if (m_ObjectBeingEdited != null && EditorUtility.IsPersistent(m_ObjectBeingEdited)) { m_AllowSceneObjects = false; } } // Set which tab should be visible at startup if (m_AllowSceneObjects) { if (obj != null) { if (typeof(Component).IsAssignableFrom(obj.GetType())) { obj = ((Component)obj).gameObject; } // Set the right tab visible (so we can see our selection) m_IsShowingAssets = EditorUtility.IsPersistent(obj); } else { m_IsShowingAssets = (requiredType != typeof(GameObject) && !typeof(Component).IsAssignableFrom(requiredType)); } } else { m_IsShowingAssets = true; } // Set member variables m_DelegateView = GUIView.current; // type filter requires unqualified names for built-in types, but will prioritize them over user types, so ensure user types are namespace-qualified if (requiredType != null) { m_RequiredType = typeof(ScriptableObject).IsAssignableFrom(requiredType) || typeof(MonoBehaviour).IsAssignableFrom(requiredType) ? requiredType.FullName : requiredType.Name; } m_SearchFilter = ""; m_OriginalSelection = obj; m_ModalUndoGroup = Undo.GetCurrentGroup(); // Freeze to prevent flicker on OSX. // Screen will be updated again when calling // SetFreezeDisplay(false) further down. ContainerWindow.SetFreezeDisplay(true); ShowWithMode(ShowMode.AuxWindow); titleContent = EditorGUIUtility.TrTextContent("Select " + (requiredType == null ? m_RequiredType : requiredType.Name)); // Deal with window size Rect p = m_Parent == null ? new Rect(0, 0, 1, 1) : m_Parent.window.position; p.width = EditorPrefs.GetFloat("ObjectSelectorWidth", 200); p.height = EditorPrefs.GetFloat("ObjectSelectorHeight", 390); position = p; minSize = new Vector2(kMinWidth, kMinTopSize + kPreviewExpandedAreaHeight + 2 * kPreviewMargin); maxSize = new Vector2(10000, 10000); SetupPreview(); // Focus Focus(); ContainerWindow.SetFreezeDisplay(false); m_FocusSearchFilter = true; // Add after unfreezing display because AuxWindowManager.cpp assumes that aux windows are added after we get 'got/lost'- focus calls. if (m_Parent != null) { m_Parent.AddToAuxWindowList(); } // Initial selection int initialSelection = obj != null?obj.GetInstanceID() : 0; if (property != null && property.hasMultipleDifferentValues) { initialSelection = 0; // don't select anything on multi selection } if (initialSelection != 0) { var assetPath = AssetDatabase.GetAssetPath(initialSelection); if (m_SkipHiddenPackages && !PackageManagerUtilityInternal.IsPathInVisiblePackage(assetPath)) { m_SkipHiddenPackages = false; } } if (ShouldTreeViewBeUsed(m_RequiredType)) { m_ObjectTreeWithSearch.Init(position, this, CreateAndSetTreeView, TreeViewSelection, ItemWasDoubleClicked, initialSelection, 0); } else { // To frame the selected item we need to wait to initialize the search until our window has been setup InitIfNeeded(); m_ListArea.InitSelection(new[] { initialSelection }); if (initialSelection != 0) { m_ListArea.Frame(initialSelection, true, false); } } }