How to get the current selected folder of "Project" Window

I have a function script that creates an asset registered with menu item “Assets/Create/MyAsset”.

It creates my asset directly under the Assets folder. Then I used Selection.activeObject, as explained here : http://forum.unity3d.com/threads/81359-how-to-get-currently-selected-folder-for-putting-new-Asset-into.

It works if I used right click to show the creation popup menu but does not work if I click on the Create Button in the toolbar of the Project Window.

I tried to add a MenuCommand to my menu item function but the context object is null.
Does anyone know how to get the current selected folder in the Project Window?

I needed this today, did a quick google… didnt find a suitable method. Heres what i came up with, works well.

Required Namespaces: UnityEngine, UnityEditor, System.IO

var path = "";
var obj = Selection.activeObject;

if (obj == null) path = "Assets";
else path = AssetDatabase.GetAssetPath(obj.GetInstanceID());

if (path.Length > 0)
{
    if (Directory.Exists(path))
    {
        Debug.Log("Folder");
    }
    else
    {
        Debug.Log("File");
    }
}
else
{
    Debug.Log("Not in assets folder");
}

Check this out:

It shows not only to get a selected folder in Project view but also all files under the selected folder even with filtering by its file extension.

    /// <summary>
    /// Retrieves selected folder on Project view.
    /// </summary>
    /// <returns></returns>
    public static string GetSelectedPathOrFallback()
    {
        string path = "Assets";
 
        foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))
        {
            path = AssetDatabase.GetAssetPath(obj);
            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                path = Path.GetDirectoryName(path);
                break;
            }
        }
        return path;
    }
 
    /// <summary>
    /// Recursively gather all files under the given path including all its subfolders.
    /// </summary>
    static IEnumerable<string> GetFiles(string path)
    {
        Queue<string> queue = new Queue<string>();
        queue.Enqueue(path);
        while (queue.Count > 0)
        {
            path = queue.Dequeue();
            try
            {
                foreach (string subDir in Directory.GetDirectories(path))
                {
                    queue.Enqueue(subDir);
                }
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex.Message);
            }
            string[] files = null;
            try
            {
                files = Directory.GetFiles(path);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex.Message);
            }
            if (files != null)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    yield return files*;*

}
}
}
}

// You can either filter files to get only neccessary files by its file extension using LINQ.
// It excludes .meta files from all the gathers file list.
var assetFiles = GetFiles(GetSelectedPathOrFallback()).Where(s => s.Contains(“.meta”) == false);

foreach (string f in assetFiles)
{
Debug.Log("Files: " + f);
}

Use built-in property

You can use built-in property to generate a “create asset” menu

[CreateAssetMenu( menuName = "Wappen Asset/WaveBankData" )]
public class WaveBankData : ScriptableObject
{

And it will magically added to right click menu → Create. Has same functionality as Unity’s one. It will be created in current browser location, prompt for a rename, etc.

alt text


As a bonus

, here is how TextMesh pro determine current right-click folder. If you call Selection.assetGUIDs under MenuItem call back, it will guarantee current displaying folder (the one that you clicked on its empty space)

    [MenuItem("Assets/Create/TextMeshPro/Color Gradient", false, 115)]
    public static void CreateColorGradient(MenuCommand context)
    {
        string filePath;

        if (Selection.assetGUIDs.Length == 0)
            filePath = "Assets/New TMP Color Gradient.asset";
        else
            filePath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]);

The TRUE Project browser current directory

Is hidden inside internal unity ProjectWindowUtil.TryGetActiveFolderPath static function and needs reflector to access it. If you are coder wiz and really want to have it, here it is. (For non coder, I wont explain this, please do C# research on your own)

using UnityEngine;
using UnityEditor;
using System.Reflection;

    // Define this function somewhere in your editor class to make a shortcut to said hidden function
	private static bool TryGetActiveFolderPath( out string path )
	{
		var _tryGetActiveFolderPath = typeof(ProjectWindowUtil).GetMethod( "TryGetActiveFolderPath", BindingFlags.Static | BindingFlags.NonPublic );

		object[] args = new object[] { null };
		bool found = (bool)_tryGetActiveFolderPath.Invoke( null, args );
		path = (string)args[0];

		return found;
	}

Note: tested in Unity 2019.4.19f

Hi!
Same problem and just figure it out!

[MenuItem("JashEditor/AssetBunldes")]
public static void CreateAssetBunldes ()
{
	Object[] selectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
	foreach(Object obj in selectedAsset)
	{
		Debug.Log("Asset name: "+obj.name+"   Type: "+obj.GetType()) ;
	}
}

Select a folder then click menu item, you will get something like this in console:

Asset name: KPacketType   Type: UnityEditor.MonoScript
Asset name: KLCPacket   Type: UnityEditor.MonoScript
Asset name: Messages   Type: UnityEngine.Object

Now you see, the only Object typed object is the folder.

NOTE:
This works works only if you put just files that unity can recognize. (PDF, jar, and other funky stuff will also be detected as UnityEngine.Object)

Doesn’t need to be more complicated than these lines

string folderPath = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
        if (folderPath.Contains("."))
            folderPath = folderPath.Remove(folderPath.LastIndexOf('/'));
        Debug.Log(folderPath);

Here you have my implementation to get the full path of a folder right-clicked on Project View.
I am not sure if this what you were asking for, but I hope it helps someone.

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);
}