Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

How to better structure hardcoded MenuItem strings in code

Discussion in 'Immediate Mode GUI (IMGUI)' started by Xarbrough, Sep 25, 2018.

  1. Xarbrough


    Dec 11, 2014
    At our team we usually implement quite a number of custom tools or ScriptableObject assets which can be used via Unity's menus like this:



    [CreateAssetMenu(fileName = "Custom Assets/Category/MyAsset")]

    We repeatedly run into the problem, that we start out small (only a few tools), but then more and more things accumulated, so we need to move things into nested menu folders to organize everything. However, the more items already exist, the more difficult it becomes to update each and every affected script, which uses a MenuItem attribute on their class. This is especially a problem for collaborating teams, where we must pay attention to merge conflicts, etc.

    My first quick fix is usually to define some const variables like this:

    Code (CSharp):
    1. public static class MenuItemPaths
    2. {
    3.     public const string ScriptableObject = "ScriptableObject";
    4.     public const string Category = "Category";
    5. }
    which makes typing (and not misspelling) easier, but it doesn't really solve the problem, that many scripts need to be updated, when we want to move menu items around into new sub-folders.

    I also thought about creating a central menu file, where all the string paths are managed and call static methods for each asset or tool, but then we have many merge conflicts in this single file.

    How do you handle this for your projects?

    Edit: Here are some more ideas, which I have tried and which help to improve working with menu items, but doesn't really fix the problem of how cumbersome it can become to move things.

    Code (CSharp):
    1. public static class EditorMenu
    2. {
    3.     public static class Tools
    4.     {
    5.         public const string root = "Aliens/";
    7.         public const string items = root + "Items/";
    8.         public const string validation = root + "Validation/";
    9.         public const string meshTools = root + "Mesh Tools/";
    10.         public const string utilities = root + "Utilities/";
    11.     }
    13.     public static class Create
    14.     {
    15.         public const string root = "ScriptableObjects/";
    17.         public const string caseData = root + "AlienConfig/";
    18.         public const string aliens = root + "Characters/";
    19.         public const string items = root + "Items/";
    20.         public const string input = root + "Input/";
    21.         public const string game = root + "Game/";
    22.         public const string debug = root + "Debug/";
    23.         public const string ui = root + "UI/";
    24.         public const string utilities = root + "Utilities/";
    25.     }
    26. }
    which can be used like so:
     [CreateAssetMenu(menuName = EditorMenu.Create.utilities + "AudioPlayable")]
    Last edited: Sep 25, 2018
  2. BinaryCats


    Feb 8, 2016
    I often get to a point in the project where its hard to remember, for example, which scriptable objects need to be created to do X. Its at that point I find it become useful to make an editor to handle it for me, or make it more clear to the user what they have to or can do