- Home /
Getting assets / sub folders inside a folder
Hi
I'm experimenting with writing an editor window that is roughly similar to the project window, but specifically aimed at browsing and previewing audio assets efficiently. Partly as it'll be useful, and partly as it is good practice! :)
What I'm stuck on is exactly how I should navigate the folder hierachy. In very rough psuedo code I expected to write something along the lines of:
void OnGUI()
{
AssetFolderGUI(Application.dataPath);
}
string AssetFolderGUI(string path)
{
//do a bit of GUI here to show the folder
//now recurse to show sub folders
string[] subfolders = GetSubFolders(path);
foreach (string foldername in fldernames)
{
AssetFolderGUI(foldername);
}
//now show the assets
string[] assetnames = GetAssets(path);
foreach (string assetname in assetnames)
{
//put some gui in
}
}
However there's no clear way to do the 'GetAssets' bit. I've seen LoadAllAssetsAtPath, but I don't want to actually load them all - I just want their names (and maybe types)! Unless I've misunderstood what 'load' really means internally.
I can see a few options:
I've misunderstood what 'load' really means internally, and its perfectly fine to just 'load' every audio asset in the project folder (even if theres 1000s)
There's no special way to do it, and I just have to check file extensions and things using the .net api
I've just missed some critical function somewhere and should have read the docs more carefully
Any help greatly appreciated!
p.s. cheeky extra question - if anybody knows any links that might show how to create the project window's 'drag-and-drop-into-inspector' behavior I'd be very greatful.
cheers
-Chris
(EDIT) done a bit more work, and here's the actual code I've written so far in case it helps.
public class Folder
{
public string path = "";
public int child_assets = 0;
public bool open = false;
public Dictionary<string, Folder> subfolders = new Dictionary<string, Folder>();
}
void OnGUI()
{
if (root == null)
{
root = new Folder();
dirty = true;
}
root.path = Application.dataPath;
if (GUILayout.Button("Refresh"))
dirty = true;
if (dirty)
{
Debug.Log("Refreshing audio folders");
RefreshFolders(root);
dirty = false;
}
scroll_pos = EditorGUILayout.BeginScrollView(scroll_pos);
FolderGUI(root);
EditorGUILayout.EndScrollView();
}
void RefreshFolders(Folder folder)
{
//mark folder and all known sub folders as having 0 relavent child assets
folder.child_assets = 0;
foreach (KeyValuePair<string, Folder> subfolder in folder.subfolders)
subfolder.Value.child_assets = 0;
//get all subdirectories of current folder, and iterate over them
string[] folder_paths = Directory.GetDirectories(folder.path);
foreach (string folder_path in folder_paths)
{
//attempt to get existing info for this folder. if it isn't already 'known', create it
Folder f;
if (!folder.subfolders.TryGetValue(folder_path, out f))
{
f = new Folder();
f.path = folder_path;
folder.subfolders.Add(f.path, f);
}
//recursively update the folder
RefreshFolders(f);
//update the child asset count
folder.child_assets += f.child_assets;
}
//quick link query to remove any detected folders that have no relevant assets in (or have been deleted)
string[] unseen = folder.subfolders.Where(a => a.Value.child_assets == 0).Select(a => a.Key).ToArray();
foreach (string s in unseen)
folder.subfolders.Remove(s);
//THIS IS THE BAD BIT! I'd like to do this properly and find all audio assets unity knows about
//count number of audio assets in this folder
string[] file_paths = Directory.GetFiles(folder.path);
foreach (string file_path in file_paths)
{
if(file_path.EndsWith(".wav"))
{
folder.child_assets++;
}
}
}
I've missed off the 'FolderGUI' function and a few other bits as they aren't relevant - the key is the bit where I iterate over files in RefreshFolder.
Answer by JedBeryll · Dec 10, 2015 at 04:39 PM
Are you doing this at runtime or editor?
If editor: use System.IO namespace and you get access to FileInfo and DirectoryInfo. Pass Application.dataPath + ".../Resources" to DirectoryInfo and you get the info of the resources folder.
If runtime: best i can think of is you can save the paths in the editor, then load that at runtime to get the paths you need.
Its at editor time, and as you say I'm using the System.IO utilities (thats where Directory. comes from). $$anonymous$$y issue is I want a better way of identifying audio assets than checking if they end in .wav. That seems very dodgy to me!
Or perhaps there isn't one, but it feels like I'm missing something - it sounds very much like a job for the AssetDatabase.