private void BuildRoots() { m_Roots = new List <RootItem>(); if (m_rootInstanceID != 0) { m_Roots.Add(new RootItem(m_rootInstanceID, null, null, true)); return; } var packagesMountPoint = PackageManager.Folders.GetPackagesPath(); var assetsFolderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID("Assets"); m_Roots.Add(new RootItem(assetsFolderInstanceID, null, null, true)); var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(skipHiddenPackages); m_Roots.Add(new RootItem(ProjectBrowser.kPackagesFolderInstanceId, packagesMountPoint, packagesMountPoint, true)); foreach (var package in packages) { var displayName = !string.IsNullOrEmpty(package.displayName) ? package.displayName : package.name; var packageFolderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(package.assetPath); if (packageFolderInstanceID == 0) { continue; } m_Roots.Add(new RootItem(packageFolderInstanceID, displayName, package.assetPath)); } }
private static IEnumerator <T> FindEverywhere <T>(SearchFilter searchFilter, Func <HierarchyProperty, T> selector) { var rootPaths = new List <string>(); if (searchFilter.searchArea == SearchFilter.SearchArea.AllAssets || searchFilter.searchArea == SearchFilter.SearchArea.InAssetsOnly) { rootPaths.Add("Assets"); } if (searchFilter.searchArea == SearchFilter.SearchArea.AllAssets || searchFilter.searchArea == SearchFilter.SearchArea.InPackagesOnly) { var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(); foreach (var package in packages) { rootPaths.Add(package.assetPath); } } foreach (var rootPath in rootPaths) { var property = new HierarchyProperty(rootPath); property.SetSearchFilter(searchFilter); while (property.Next(null)) { yield return(selector(property)); } } }
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(); }
static bool AnyTargetMaterialHasChildren(string[] targetPaths) { GUID[] guids = targetPaths.Select(path => AssetDatabase.GUIDFromAssetPath(path)).ToArray(); Func <string, bool> HasChildrenInPath = (string rootPath) => { var property = new HierarchyProperty(rootPath, false); property.SetSearchFilter(new SearchFilter { classNames = new string[] { "Material" }, searchArea = SearchFilter.SearchArea.AllAssets }); while (property.Next(null)) { GUID parent; var child = InternalEditorUtility.GetLoadedObjectFromInstanceID(property.GetInstanceIDIfImported()) as Material; if (child) { if (AssetDatabase.IsForeignAsset(child)) { continue; } parent = AssetDatabase.GUIDFromAssetPath(AssetDatabase.GetAssetPath(child.parent)); } else { var path = AssetDatabase.GUIDToAssetPath(property.guid); if (!path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase)) { continue; } parent = EditorMaterialUtility.GetMaterialParentFromFile(path); } for (int i = 0; i < guids.Length; i++) { if (guids[i] == parent) { return(true); } } } return(false); }; if (HasChildrenInPath("Assets")) { return(true); } foreach (var package in PackageManagerUtilityInternal.GetAllVisiblePackages(false)) { if (package.source == PackageManager.PackageSource.Local && HasChildrenInPath(package.assetPath)) { return(true); } } return(false); }
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 + "'"); } } }
static void ReparentMaterialChildren(string assetPath) { var toDelete = AssetDatabase.LoadAssetAtPath <Material>(assetPath); var toDeleteGUID = AssetDatabase.GUIDFromAssetPath(assetPath); var newParent = toDelete.parent; Action <string> ReparentInPath = (string rootPath) => { var property = new HierarchyProperty(rootPath, false); property.SetSearchFilter(new SearchFilter { classNames = new string[] { "Material" }, searchArea = SearchFilter.SearchArea.AllAssets }); while (property.Next(null)) { var child = InternalEditorUtility.GetLoadedObjectFromInstanceID(property.GetInstanceIDIfImported()) as Material; if (!child) { // First check guid from file to avoid loading all materials in memory string path = AssetDatabase.GUIDToAssetPath(property.guid); if (EditorMaterialUtility.GetMaterialParentFromFile(path) != toDeleteGUID) { continue; } child = AssetDatabase.LoadAssetAtPath <Material>(path); } if (child != null && child.parent == toDelete && !AssetDatabase.IsForeignAsset(child)) { child.parent = newParent; } } }; ReparentInPath("Assets"); foreach (var package in PackageManagerUtilityInternal.GetAllVisiblePackages(false)) { if (package.source == PackageManager.PackageSource.Local) { ReparentInPath(package.assetPath); } } }
static IEnumerator <HierarchyProperty> FindInAllAssets(SearchFilter searchFilter) { var rootPaths = new List <string>(); rootPaths.Add("Assets"); foreach (var package in PackageManagerUtilityInternal.GetAllVisiblePackages(false)) { if (package.source == PackageManager.PackageSource.Local) { rootPaths.Add(package.assetPath); } } foreach (var rootPath in rootPaths) { var property = new HierarchyProperty(rootPath, false); property.SetSearchFilter(searchFilter); while (property.Next(null)) { yield return(property); } } }
void SearchInFolders() { List <FilterResult> list = new List <FilterResult>(); List <string> baseFolders = new List <string>(); baseFolders.AddRange(ProjectWindowUtil.GetBaseFolders(m_SearchFilter.folders)); if (baseFolders.Remove(PackageManager.Folders.GetPackagesPath())) { var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(m_SearchFilter.skipHidden); foreach (var package in packages) { if (!baseFolders.Contains(package.assetPath)) { baseFolders.Add(package.assetPath); } } } m_SearchFilter.searchArea = SearchFilter.SearchArea.SelectedFolders; foreach (string folderPath in baseFolders) { // Ensure we do not have a filter when finding folder HierarchyProperty property = new HierarchyProperty(folderPath); property.SetSearchFilter(m_SearchFilter); // Set filter after we found the folder int folderDepth = property.depth; int[] expanded = null; // enter all children of folder while (property.NextWithDepthCheck(expanded, folderDepth + 1)) { FilterResult result = new FilterResult(); CopyPropertyData(ref result, property); list.Add(result); } } m_Results = list.ToArray(); }
private HashSet <int> GetParentsBelow(int id) { // Add all children expanded ids to hashset HashSet <int> parentsBelow = new HashSet <int>(); // Check if packages instance if (id == ProjectBrowser.kPackagesFolderInstanceId) { parentsBelow.Add(id); var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(skipHiddenPackages); foreach (var package in packages) { var packageFolderInstanceId = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(package.assetPath); parentsBelow.UnionWith(GetParentsBelow(packageFolderInstanceId)); } return(parentsBelow); } var path = AssetDatabase.GetAssetPath(id); IHierarchyProperty search = new HierarchyProperty(path); if (search.Find(id, null)) { parentsBelow.Add(id); int depth = search.depth; while (search.Next(null) && search.depth > depth) { if (search.isFolder && search.hasChildren) { parentsBelow.Add(search.instanceID); } } } return(parentsBelow); }
public override void FetchData() { m_RootItem = new TreeViewItem(0, 0, null, "Invisible Root Item"); SetExpanded(m_RootItem, true); // ensure always visible Texture2D folderIcon = EditorGUIUtility.FindTexture(EditorResources.folderIconName); // We want three roots: Favorites, Assets, and Saved Filters List <TreeViewItem> visibleRoots = new List <TreeViewItem>(); // Fetch asset folders int assetsFolderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID("Assets"); int depth = 0; string displayName = "Assets"; //CreateDisplayName (assetsFolderInstanceID); AssetsTreeViewDataSource.RootTreeItem assetRootItem = new AssetsTreeViewDataSource.RootTreeItem(assetsFolderInstanceID, depth, m_RootItem, displayName); assetRootItem.icon = folderIcon; ReadAssetDatabase("Assets", assetRootItem, depth + 1); // Fetch packages folder displayName = PackageManager.Folders.GetPackagesPath(); AssetsTreeViewDataSource.RootTreeItem packagesRootItem = new AssetsTreeViewDataSource.RootTreeItem(ProjectBrowser.kPackagesFolderInstanceId, depth, m_RootItem, displayName); depth++; packagesRootItem.icon = folderIcon; var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(skipHiddenPackages); foreach (var package in packages) { var packageFolderInstanceId = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(package.assetPath); displayName = !string.IsNullOrEmpty(package.displayName) ? package.displayName : package.name; AssetsTreeViewDataSource.PackageTreeItem packageItem = new AssetsTreeViewDataSource.PackageTreeItem(packageFolderInstanceId, depth, packagesRootItem, displayName); packageItem.icon = folderIcon; packagesRootItem.AddChild(packageItem); ReadAssetDatabase(package.assetPath, packageItem, depth + 1); } // Fetch saved filters TreeViewItem savedFiltersRootItem = SavedSearchFilters.ConvertToTreeView(); savedFiltersRootItem.parent = m_RootItem; // Order visibleRoots.Add(savedFiltersRootItem); visibleRoots.Add(assetRootItem); visibleRoots.Add(packagesRootItem); m_RootItem.children = visibleRoots; // Get global expanded state of roots foreach (TreeViewItem item in m_RootItem.children) { // Do not expand Packages root item if (item.id == ProjectBrowser.kPackagesFolderInstanceId) { continue; } bool expanded = EditorPrefs.GetBool(kProjectBrowserString + item.displayName, true); SetExpanded(item, expanded); } m_NeedRefreshRows = true; }
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); } } }
public override void FetchData() { bool firstInitialize = !isInitialized; m_RootItem = new TreeViewItem(0, 0, null, "Invisible Root Item"); SetExpanded(m_RootItem, true); // ensure always visible // We want three roots: Favorites, Assets, and Packages List <TreeViewItem> visibleRoots = new List <TreeViewItem>(); // Favorites root TreeViewItem savedFiltersRootItem = SavedSearchFilters.ConvertToTreeView(); visibleRoots.Add(savedFiltersRootItem); // Assets root int assetsFolderInstanceID = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID("Assets"); int depth = 0; string displayName = "Assets"; AssetsTreeViewDataSource.RootTreeItem assetRootItem = new AssetsTreeViewDataSource.RootTreeItem(assetsFolderInstanceID, depth, m_RootItem, displayName); assetRootItem.icon = s_FolderIcon; visibleRoots.Add(assetRootItem); // Packages root displayName = PackageManager.Folders.GetPackagesPath(); AssetsTreeViewDataSource.RootTreeItem packagesRootItem = new AssetsTreeViewDataSource.RootTreeItem(ProjectBrowser.kPackagesFolderInstanceId, depth, m_RootItem, displayName); packagesRootItem.icon = s_FolderIcon; visibleRoots.Add(packagesRootItem); m_RootItem.children = visibleRoots; // Set global expanded state for roots from EditorPrefs (must be before building the rows) if (firstInitialize) { foreach (TreeViewItem item in m_RootItem.children) { bool expanded = EditorPrefs.GetBool(kProjectBrowserString + item.displayName, true); SetExpanded(item, expanded); } } // Build rows //----------- m_Rows = new List <TreeViewItem>(100); // Favorites savedFiltersRootItem.parent = m_RootItem; m_Rows.Add(savedFiltersRootItem); if (IsExpanded(savedFiltersRootItem)) { foreach (var f in savedFiltersRootItem.children) { m_Rows.Add(f); } } else { savedFiltersRootItem.children = CreateChildListForCollapsedParent(); } // Asset folders m_Rows.Add(assetRootItem); ReadAssetDatabase("Assets", assetRootItem, depth + 1, m_Rows); // Individual Package folders (under the Packages root item) m_Rows.Add(packagesRootItem); var packages = PackageManagerUtilityInternal.GetAllVisiblePackages(skipHiddenPackages); if (IsExpanded(packagesRootItem)) { depth++; foreach (var package in packages) { var packageFolderInstanceId = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID(package.assetPath); displayName = !string.IsNullOrEmpty(package.displayName) ? package.displayName : package.name; AssetsTreeViewDataSource.PackageTreeItem packageItem = new AssetsTreeViewDataSource.PackageTreeItem(packageFolderInstanceId, depth, packagesRootItem, displayName); packageItem.icon = s_FolderIcon; packagesRootItem.AddChild(packageItem); m_Rows.Add(packageItem); ReadAssetDatabase(package.assetPath, packageItem, depth + 1, m_Rows); } } else { if (packages.Length > 0) { packagesRootItem.children = CreateChildListForCollapsedParent(); } } m_NeedRefreshRows = false; }