Hi, I want to create prefabs via the right click menu directly inside the project:

I know I can create prefabs inside the Hierarchy with:
[MenuItem("GameObject/MyAssets/Prefab", false, TeasersPriority)]
MyCreateFunction()
But this only works inside the scene hierarchy.
I know I can create Scriptable Objects with:
[CreateAssetMenu(fileName = "Prefab", menuName = "MyAssets/Prefab")]
public class MySO : ScriptableObject
But I need a mixture of two. I need the CreateAssetMenu to spawn a prefab just like a scriptable object, direct in my project tree.
How is it done?
[MenuItem("FooBar/Prefab")]
private static void PrefabC() {
var assetPath = "Assets/MyTempPrefab.prefab";
var source = new GameObject("Root");
var childA = new GameObject("A");
childA.transform.parent = source.transform;
PrefabUtility.SaveAsPrefabAsset(source, assetPath);
}
Adapted from here:
https://docs.unity3d.com/ScriptReference/PrefabUtility.EditPrefabContentsScope.html
Okay, I gave MenuItem another shot, and fair enough, of course I could add it to the Create menu.
The only thing you need to know is, that right clicking the project tab is the same as going to Assets over the top menu.
So what I had to do was the following:
[MenuItem("Assets/Create/MyPrefab")]
CreatePrefabInProject("MyPrefab")
Next problem was, from here I couldn’t get the currently open folder path. I stumbled across a post to get it via reflection, so I added this for our utils class:
public static string CurrentProjectFolderPath
{
get
{
Type projectWindowUtilType = typeof(ProjectWindowUtil);
MethodInfo getActiveFolderPath = projectWindowUtilType.GetMethod("GetActiveFolderPath", BindingFlags.Static | BindingFlags.NonPublic);
object obj = getActiveFolderPath.Invoke(null, new object[0]);
return obj.ToString();
}
}
Next up was to actually create a copy of the prefab template, which I did via the AssetDatabase.CopyAsset() function, since this seemed to be the most straight forward way:
private static void CreatePrefabInProject(string prefabName)
{
var prefab = UnityEngine.Resources.Load(prefabName);
string targetPath = $"{CurrentProjectFolderPath}/{prefabName}.prefab";
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(prefab), targetPath);
}
The template prefabs were therefor placed inside a Resource Folder like so:
Resources/MyPrefab