(Editor) How to add Checkmarks to MenuItems

Trying to write an Editor script that uses toggle-able MenuItems. If you look at “Edit->Graphics Emulation”. You’ll see group of items, but only 1 can be checked on at a time. I would like to simulate the same behavior. But I don’t know how, is there an undocumented attribute I’m missing?

Couldn’t find anything about checkmarks here: http://docs.unity3d.com/ScriptReference/MenuItem.html

Was searching for this answer too. Here’s what I found:

Menu.SetChecked gives you the ability to mark menu items with the checkmark seen in Edit > Graphics Emulation. Wrote a small example of this that also leverages EditorPrefs, since there’s a little gotcha when setting the checked state on load.

using UnityEditor;

[InitializeOnLoad]
public static class CheckmarkMenuItem {

    private const string MENU_NAME = "Example/Toggle";

    private static bool enabled_;

    /// Called on load thanks to the InitializeOnLoad attribute
    static CheckmarkMenuItem() {

        CheckmarkMenuItem.enabled_ = EditorPrefs.GetBool(CheckmarkMenuItem.MENU_NAME, false);

        /// Delaying until first editor tick so that the menu
        /// will be populated before setting check state, and
        /// re-apply correct action
        EditorApplication.delayCall += () => {
            PerformAction(CheckmarkMenuItem.enabled_);
        };
    }

    [MenuItem(CheckmarkMenuItem.MENU_NAME)]
    private static void ToggleAction() {

        /// Toggling action
        PerformAction( !CheckmarkMenuItem.enabled_);
    }

    public static void PerformAction(bool enabled) {

        /// Set checkmark on menu item
        Menu.SetChecked(CheckmarkMenuItem.MENU_NAME, enabled);
        /// Saving editor state
        EditorPrefs.SetBool(CheckmarkMenuItem.MENU_NAME, enabled);

        CheckmarkMenuItem.enabled_ = enabled;

        /// Perform your logic here...
    }
}

@Mikeysee 's approach is nice, but can be improved a little imho:

public static class MyMenu
{
    private const string MenuName = "My Menu Item";
    private const string SettingName = "MySetting";

    public static bool IsEnabled
    {
        get { return EditorPrefs.GetBool(SettingName, true); }
        set { EditorPrefs.SetBool(SettingName, value); }
    }
         
    [MenuItem(MenuName)]
    private static void ToggleAction()
    {
        IsEnabled = !IsEnabled;
    }
 
    [MenuItem(MenuName, true)]
    private static bool ToggleActionValidate()
    {
        Menu.SetChecked(MenuName, IsEnabled);
        return true;
    }
}

For anyone that still having issues with this, the correct way to check/unchek a menu is having a function to do the actual menu action, and another to do the menu validation, where you can check or uncheck it, like in this example:

This is the only method that will keep your menu checking state even after you hit the “play” button.

@rickomax has the correct solution.

Here is a simplified working version of his code:

[InitializeOnLoad]
public static class MyMenu
{
    private const string MenuName = "My Menu Item";

    public static bool isEnabled;

    static MyMenu()
    {
        isEnabled = EditorPrefs.GetBool(MenuName, true);
    }

    [MenuItem(MenuName)]
    private static void ToggleAction()
    {
        isEnabled = !isEnabled;
        EditorPrefs.SetBool(MenuName, isEnabled);
    }

    [MenuItem(MenuName, true)]
    private static bool ToggleActionValidate()
    {
        Menu.SetChecked(MenuName, isEnabled);
        return true;
   }
}

Been trying to solve this one for some time, whilst the underlying value appears to work, the visible state of the menu item does not seem to persist when first navigating to the menu item. Does the Menu.SetChecked method actually set the appearance to checked?

[InitializeOnLoad]
public class OptionsMenu
{
    private const string MenuName = "Options/Toggle";
    private static bool isToggled;

    static OptionsMenu()
    {
        EditorApplication.delayCall += () =>
        {
            isToggled = EditorPrefs.GetBool(MenuName, true);
            SetMode(isToggled);
            Menu.SetChecked(MenuName, isToggled); // This doesn't appear to work
        };
    }

    [MenuItem(MenuName)]
    private static void ToggleMode()
    {
        isToggled = !isToggled;
        SetMode(isToggled);
        Menu.SetChecked(MenuName, isToggled);
        EditorPrefs.SetBool(MenuName, isToggled);
    }

    private static void SetMode(bool value)
    {
        // Mode set up here...
    }
}