Hide folders with no unused assets from tree view
Zeblote opened this issue · 12 comments
The tree view is working really well, but I noticed that the folder tree shows every folder in the project, rather than only ones that actually have unused assets in them. Is it possible to filter the folders and hide ones that will display "no assets"?
Actually it was intentional , so you can see list of empty folders in project.
But I think some kind of checkbox in configs can show/hide empty folders, like "Show Empty Folders" .
I will check it out.
I see. But that doesn't work in practice, does it? Like, both folders that are empty and folders that have only assets in use in them will be shown here, and there is no way to tell them apart in the unused assets tab.
Maybe empty folders could be a separate view, but I'm not convinced that is actually useful. Folders are typically not tracked by version control so deleting them doesn't really do much, and they'd be gone if you make a fresh workspace anyway.
Agree, that logical, its kinda one side perspective, when you developing it :)
So you suggest:
Folder has unused assets -> Show
Folder does not have unused assets, and its not empty -> Hide
Folder does not have unused assets and its empty -> Hide
Right?
Yeah, that would make the most sense to me. After all, the purpose of this view is to drill down on unused assets and nothing else, so folders that have no unused assets are not relevant
I was thinking about seperate view for empty folders, but its kinda redundant.
Now i am thinking about adding seperate tab for assets that has external referencers (Outside "/Game" folder).
Like if you created some Blueprint in "Engine Folder" content and then used static meshes from "/Game" folder.
That's interesting, thinking about it I don't remember ever encountering such a case (game content referenced from engine). I'd expect that view to be empty for basically all projects, but you never know, might be useful for sanity checking/debug.
If that the case it most likely accidental I think. I encountered it , in one of our project, artist just moved asset to wrong folder, then I couldnt find that asset, until traced it with reference viewer :)
Like you said it more like validation check for assets to be in their proper location.
Hi @Zeblote
I recently worked on this issue, but came to problem when trying to hide folders in PathPicker.
Seems like engine module ContentBrowser
dont have any public API that would accept path as exclude options. Those functions are internal for ContentBrowser
module itself. I tried to understand how for example Show Engine Content
check box works, and tried to implement it, but turns out its hard coded in engine code.
Here is some code examples
// file Engine\Source\Editor\ContentBrowserData\Public\ContentBrowserDataFilter.h
/** Flags controlling which item attributes should be included */
UENUM()
enum class EContentBrowserItemAttributeFilter : uint8
{
IncludeNone = 0,
IncludeProject = 1<<0,
IncludeEngine = 1<<1,
IncludePlugins = 1<<2,
IncludeDeveloper = 1<<3,
IncludeLocalized = 1<<4,
IncludeAll = IncludeProject | IncludeEngine | IncludePlugins | IncludeDeveloper | IncludeLocalized,
};
ENUM_CLASS_FLAGS(EContentBrowserItemAttributeFilter);
and SPathView
class that are responsible for ContentBrowser
path UI
const UContentBrowserSettings* ContentBrowserSettings = GetDefault<UContentBrowserSettings>();
FContentBrowserDataFilter DataFilter;
DataFilter.bRecursivePaths = true;
DataFilter.ItemTypeFilter = EContentBrowserItemTypeFilter::IncludeFolders;
DataFilter.ItemCategoryFilter = InitialCategoryFilter;
if (bAllowClassesFolder && ContentBrowserSettings->GetDisplayCppFolders())
{
DataFilter.ItemCategoryFilter |= EContentBrowserItemCategoryFilter::IncludeClasses;
}
else
{
DataFilter.ItemCategoryFilter &= ~EContentBrowserItemCategoryFilter::IncludeClasses;
}
DataFilter.ItemCategoryFilter &= ~EContentBrowserItemCategoryFilter::IncludeCollections;
DataFilter.ItemAttributeFilter = EContentBrowserItemAttributeFilter::IncludeProject
| (ContentBrowserSettings->GetDisplayEngineFolder() ? EContentBrowserItemAttributeFilter::IncludeEngine : EContentBrowserItemAttributeFilter::IncludeNone)
| (ContentBrowserSettings->GetDisplayPluginFolders() ? EContentBrowserItemAttributeFilter::IncludePlugins : EContentBrowserItemAttributeFilter::IncludeNone)
| (ContentBrowserSettings->GetDisplayDevelopersFolder() ? EContentBrowserItemAttributeFilter::IncludeDeveloper : EContentBrowserItemAttributeFilter::IncludeNone)
| (ContentBrowserSettings->GetDisplayL10NFolder() ? EContentBrowserItemAttributeFilter::IncludeLocalized : EContentBrowserItemAttributeFilter::IncludeNone);
TSharedPtr<FBlacklistPaths> CombinedFolderBlacklist;
if ((FolderBlacklist && FolderBlacklist->HasFiltering()) || (WritableFolderBlacklist && WritableFolderBlacklist->HasFiltering() && !bAllowReadOnlyFolders))
{
CombinedFolderBlacklist = MakeShared<FBlacklistPaths>();
if (FolderBlacklist)
{
CombinedFolderBlacklist->Append(*FolderBlacklist);
}
if (WritableFolderBlacklist && !bAllowReadOnlyFolders)
{
CombinedFolderBlacklist->Append(*WritableFolderBlacklist);
}
}
if (PluginPathFilters.IsValid() && PluginPathFilters->Num() > 0 && ContentBrowserSettings->GetDisplayPluginFolders())
{
TArray<TSharedRef<IPlugin>> Plugins = IPluginManager::Get().GetEnabledPluginsWithContent();
for (const TSharedRef<IPlugin>& Plugin : Plugins)
{
if (!PluginPathFilters->PassesAllFilters(Plugin))
{
FString MountedAssetPath = Plugin->GetMountedAssetPath();
MountedAssetPath.RemoveFromEnd(TEXT("/"), ESearchCase::CaseSensitive);
if (!CombinedFolderBlacklist.IsValid())
{
CombinedFolderBlacklist = MakeShared<FBlacklistPaths>();
}
CombinedFolderBlacklist->AddBlacklistItem("PluginPathFilters", MountedAssetPath);
}
}
}
ContentBrowserUtils::AppendAssetFilterToContentBrowserFilter(FARFilter(), nullptr, CombinedFolderBlacklist, DataFilter);
FContentBrowserDataCompiledFilter CompiledDataFilter;
{
static const FName RootPath = "/";
UContentBrowserDataSubsystem* ContentBrowserData = IContentBrowserDataModule::Get().GetSubsystem();
ContentBrowserData->CompileFilter(RootPath, DataFilter, CompiledDataFilter);
}
return CompiledDataFilter;
BlacklistItems
maybe solution, but its kinda private to module :(
So to implement this we have 2 options.
- change engine code, which its not an option if I want plugin be compatible and available in marketplace
- create custom ContentBrowserUI
Second option maybe solution, but it will take too much time on development, I think its not worth the effort for this feature.
PS. I will keep this issue open, if someone will help me with this.
Thanks
Now Empty folders can be hidden in unreal engine 5 content browser settings.