Daniel Lip
Daniel Lip

Reputation: 11329

How can I loop over sub folders in Assets folder?

string selectedPath = GetPath();
var subFolders = AssetDatabase.GetSubFolders(selectedPath);
List<string> paths = new List<string>();
foreach(string path in subFolders)
{
    paths.Add(path);
}

For example the subFolders is Assets/My Folder but under My Folder there are many more subfolders.

AssetDatabase.GetSubFolders don't make recursive it's getting the first sub folder only. I want to get all the sub folders recursive.

I tried :

List paths = new List(); foreach(string path in subFolders) { paths.Add(path); }

but it's still giving me only the first sub folder.

This is how I'm getting the selected path name in the Assets :

[MenuItem("Assets/Get Path")]
private static string GetClickedDirFullPath()
{
    string clickedAssetGuid = Selection.assetGUIDs[0];
    string clickedPath = AssetDatabase.GUIDToAssetPath(clickedAssetGuid);
    string clickedPathFull = Path.Combine(Directory.GetCurrentDirectory(), clickedPath);

    FileAttributes attr = File.GetAttributes(clickedPathFull);
    return attr.HasFlag(FileAttributes.Directory) ? clickedPathFull : Path.GetDirectoryName(clickedPathFull);
}

[MenuItem("Assets/Get Path")]
private static string GetPath()
{
    string path = GetClickedDirFullPath();
    int index = path.IndexOf("Assets");
    string result = path.Substring(index);

    return result;
}

Upvotes: 0

Views: 800

Answers (2)

derHugo
derHugo

Reputation: 90580

You could simply make it recursive using List<T>.AddRange like

private static string[] GetSubFoldersRecursive(string root)
{
    var paths = new List<string>();

    // If there are no further subfolders then AssetDatabase.GetSubFolders returns 
    // an empty array => foreach will not be executed
    // This is the exit point for the recursion
    foreach (var path in AssetDatabase.GetSubFolders(root))
    {
        // add this subfolder itself
        paths.Add(path);

        // If this has no further subfolders then simply no new elements are added
        paths.AddRange(GetSubFoldersRecursive(path));
    }

    return paths.ToArray();
}

So e.g.

[ContextMenu("Test")]
private void Test()
{
    var sb = new StringBuilder();

    var folders = SubFolders("Assets");

    if(folders.Length > 0)
    {
        foreach (var folder in SubFolders("Assets"))
        {
            sb.Append(folder).Append('\n');
        }
    }
    else
    {
        sb.Append(" << The given path has no subfolders! >>");
    }

    Debug.Log(sb.ToString());
}

will print out the entire project's folder structure.

For

enter image description here

I get

Assets/Example 1
Assets/Example 1/SubFolder A
Assets/Example 1/SubFolder B
Assets/Example 1/SubFolder C
Assets/Example 2
Assets/Example 2/SubFolder A
Assets/Example 2/SubFolder A/SubSubFolder A

So in your case it would be

string selectedPath = GetPath();
var folders = SubFolders(selectedPath);
foreach(var path in folders)
{
    ...
}

Upvotes: 4

Kalpesh Dabhi
Kalpesh Dabhi

Reputation: 802

Try this code for get recursive folder path

    //this is your code
    string selectedPath = GetPath();
    var subFolders = AssetDatabase.GetSubFolders(selectedPath);
    List<string> paths = new List<string>();
    if(subFolders != null)
    {
        foreach(string path in subFolders)
        {
            GetAllRecursiveFolder(path,ref paths);
        }
    }
    else
    {
        paths.add(selectedPath);
    }


    public void GetAllRecursiveFolder(string currentPath,ref List<string> paths)
    {

        var subFolders = AssetDatabase.GetSubFolders(currentPath);
        if(subFolders != null)
        {
            foreach(string path in subFolders)
            {
                GetAllRecursiveFolder(path,ref paths);// Get recursive folder path, and stored in ref variable
            }
        }
        else
        {
            paths.add(currentPath);
        }

    }

Upvotes: 2

Related Questions