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