Is it possible to set the order of folders when using CreateAssetMenu
for scriptable objects?
For example, if I have these classes
[CreateAssetMenu(menuName = "My Objects/First Thing", order = 1)]
public class FirstThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Second Thing", order = 2)]
public class SecondThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Third Thing", order = 3)]
public class ThirdThing : ScriptableObject
{
}
Then when I right click in the Project window and select Create, the context menu shows my menu options in this order
Create -> My Objects -> First Thing
|-----------> Second Thing
|-----------> Third Thing
However, once I start organizing my menu options into subfolders, I can't find a way to control the order of subfolders. For instance, if I now have this
[CreateAssetMenu(menuName = "My Objects/Things/First Thing", order = 1)]
public class FirstThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Things/Second Thing", order = 2)]
public class SecondThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Things/Third Thing", order = 3)]
public class ThirdThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Widgets/First Widget", order = 1)]
public class FirstWidget: ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Widgets/Second Widget", order = 2)]
public class SecondWidget: ScriptableObject
{
}
Now the Create context menu looks like this
Create -> My Objects -> Things --> First Thing
| |--------> Second Thing
| |--------> Third Thing
|-----------> Widgets -> First Widget
|--------> Second Widget
Is there a way to control the order of the Things
and Widgets
folders similarly to how I can control the order of First Thing
, Second Thing
, etc. within their parent folders?
From this post which spreads some details about the sorting order in Unity menus under Sorting Details
further below you can find that:
Sort priority for custom submenu groups themselves (as opposed to the menu item) is a bit tricky. A submenu group will be sorted at whatever priority the custom menu item had when it was first created.
Or in other words: Subfolders are sorted by the order
value of the first element within them.
Since both your subfolders start with the order 1
they are sorted alphabetic as fallback.
So in order to bring the Things
menu under the Widgets
folder simply make sure the elements have an absolute higher value like e.g.
[CreateAssetMenu(menuName = "My Objects/Things/First Thing", order = 11)]
public class FirstThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Things/Second Thing", order = 12)]
public class SecondThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Things/Third Thing", order = 13)]
public class ThirdThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Widgets/First Widget", order = 1)]
public class FirstWidget: ScriptableObject
{
}
[CreateAssetMenu(menuName = "My Objects/Widgets/Second Widget", order = 2)]
public class SecondWidget: ScriptableObject
{
}
Maybe it would even be enough to instead make it 2, 3, 4
on the Things
items ;)
This should result in
Create -> My Objects -> Widgets -> First Widget
| |--------> Second Widget
|
|-----------> Things --> First Thing
|--------> Second Thing
|--------> Third Thing
Additionally note
If your item has a priority of
11
or more than the previous item, Unity will create a separator before your item
And careful:
As a quick aside, if you change a menu item’s existing sort priority, you may not see it reflected in the Menus. I think Unity is caching the value, so to get it to update you can either restart your Editor, or do some gymnastics where you first remove the Priority from your attribute, compile, then add the new priority.
Little pro tip: To make maintenance easier I usually would have a central class with some constants and doing e.g.
public static class Constants
{
public static string MENU = "My Objects/";
public static string MENU_THINGS = MENU + "Things/";
public static string MENU_WIDGETS = MENU + "Widgets/";
public static int ORDER_WIDGETS = 0;
public static int ORDER_THINGS = 10;
}
and then do
[CreateAssetMenu(menuName = Constants.MENU_THINGS + "First Thing", order = Constants.ORDER_THINGS + 1)]
public class FirstThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = Constants.MENU_THINGS + "Second Thing", order = Constants.ORDER_THINGS + 2)]
public class SecondThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = Constants.MENU_THINGS + "Third Thing", order = Constants.ORDER_THINGS + 3)]
public class ThirdThing : ScriptableObject
{
}
[CreateAssetMenu(menuName = Constants.MENU_WIDGETS + "First Widget", order = Constants.ORDER_WIDGETS + 1)]
public class FirstWidget: ScriptableObject
{
}
[CreateAssetMenu(menuName = Constants.MENU_WIDGETS + "Second Widget", order = Constants.ORDER_WIDGETS + 2)]
public class SecondWidget: ScriptableObject
{
}