Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
5
Question by Jessespike · Aug 21, 2014 at 07:51 PM · editormenuitemcheckbox

(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

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jessespike · Aug 21, 2014 at 09:40 PM 0
Share

Haven't resolved this yet, but as a temporary workaround, I'm using the PreferenceItem attribute. http://docs.unity3d.com/412/Documentation/ScriptReference/PreferenceItem.html

4 Replies

· Add your reply
  • Sort: 
avatar image
8
Best Answer

Answer by Ziugy · Feb 25, 2016 at 08:27 AM

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...
     }
 }


Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ThomLaurent · Jan 29, 2017 at 12:47 PM 0
Share

@Ziugy Your little gotcha doesn't work when you switch to play mode, any idea ?

avatar image Ziugy ThomLaurent · Jan 30, 2017 at 09:34 PM 0
Share

Good question. I didn't see this kind of issue before, but it is presenting itself now. $$anonymous$$y assumptions are this was either overlooked when I created this, $$anonymous$$ac vs Windows (I wrote this originally on $$anonymous$$ac), or the latest version of Unity is presenting this issue (I was using the latest at the time, 4.6 or 4.7). I wasn't able to find a work-around with my brief investigation: EditorApplication.update ins$$anonymous$$d of delayCall, removing InitializeOnLoad, skipping delayCall if going into play mode.

avatar image Gibibit · May 23, 2017 at 10:57 AM 0
Share

Using EditorPrefs in a (static) constructor is a race condition which has been cleared up with errors in v5.4 since June of 2016: https://blogs.unity3d.com/2016/06/06/serialization-monobehaviour-constructors-and-unity-5-4/

The static constructor should be as such:

 static Checkmark$$anonymous$$enuItem() {
  
          /// Delaying until first editor tick so that the menu
          /// will be populated before setting check state, and
          /// re-apply correct action.
          /// The same goes for getting the preference from EditorPrefs
          /// as it might not be initialized during the constructor call time
          EditorApplication.delayCall += () => {
              Checkmark$$anonymous$$enuItem.enabled_ = EditorPrefs.GetBool(
                  Checkmark$$anonymous$$enuItem.$$anonymous$$ENU_NA$$anonymous$$E, false);
              PerformAction(Checkmark$$anonymous$$enuItem.enabled_);
          };
      }

I$$anonymous$$O it's more consistent to call EditorPrefs.GetBool() in every local scope ins$$anonymous$$d of storing it in a static variable. But that's a bit of a personal choice.

avatar image
10

Answer by JanWosnitzaSAS · Jul 04, 2018 at 02:05 PM

@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;
     }
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NikolayBebopbee · Jan 24, 2019 at 01:40 PM 1
Share

Well done! and more over it's not improvement it's more proper way to handle $$anonymous$$enu.SetChecked. Only in my way I moved SetChecked to the IsEnable setter. This answer have to be at first position here.

avatar image pandolfini NikolayBebopbee · Jul 14, 2021 at 02:14 PM 0
Share

Agreed--this is the only way to maintain the check mark appropriately in the editor on first load.

avatar image
6

Answer by rickomax · Jul 04, 2017 at 10:49 PM

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:

https://github.com/HearthSim/unity-examples/blob/master/AssetBundleTest/Project/Assets/AssetBundleManager/Editor/LaunchAssetBundleServer.cs

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

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image bodedoctor · Jul 23, 2017 at 10:48 AM 0
Share

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 $$anonymous$$enu.SetChecked method actually set the appearance to checked?

 [InitializeOnLoad]
 public class Options$$anonymous$$enu
 {
     private const string $$anonymous$$enuName = "Options/Toggle";
     private static bool isToggled;
 
     static Options$$anonymous$$enu()
     {
         EditorApplication.delayCall += () =>
         {
             isToggled = EditorPrefs.GetBool($$anonymous$$enuName, true);
             Set$$anonymous$$ode(isToggled);
             $$anonymous$$enu.SetChecked($$anonymous$$enuName, isToggled); // This doesn't appear to work
         };
     }
 
     [$$anonymous$$enuItem($$anonymous$$enuName)]
     private static void Toggle$$anonymous$$ode()
     {
         isToggled = !isToggled;
         Set$$anonymous$$ode(isToggled);
         $$anonymous$$enu.SetChecked($$anonymous$$enuName, isToggled);
         EditorPrefs.SetBool($$anonymous$$enuName, isToggled);
     }
 
     private static void Set$$anonymous$$ode(bool value)
     {
         // $$anonymous$$ode set up here...
     }
 }
avatar image vexe · Oct 08, 2017 at 02:03 AM 0
Share

This should be the accepted answer!

avatar image
2

Answer by Mikeysee · May 01, 2018 at 01:33 AM

@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;
    }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

31 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A node in a childnode? 1 Answer

Menu Items as checkboxes/radio buttons 4 Answers

Network - Editor + Builds = Problem with RayCasts? 0 Answers

How to check if object is skewed ? 2 Answers

Determine the Scene that is selected when using context menu 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges