Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We're looking for insight from anyone who has experience with game testing to help us better Unity. Take our survey here. If chosen to participate you'll be entered into a sweepstake to win an Amazon gift card.
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Unity 2018.3 is now released.
    Dismiss Notice
  6. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

How to better structure hardcoded MenuItem strings in code

Discussion in 'Extensions & OnGUI' started by Xarbrough, Sep 25, 2018.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    310
    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:

    [UnityEditor.MenuItem("ScriptableObjects/Category/Special/MyObject")]


    or

    [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/";
    6.  
    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.     }
    12.  
    13.     public static class Create
    14.     {
    15.         public const string root = "ScriptableObjects/";
    16.  
    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

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    152
    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