Search Unity

Request: Mac Menu Bar Support

Discussion in 'macOS' started by Arthur-LVGameDev, Jan 9, 2019.

  1. Arthur-LVGameDev

    Arthur-LVGameDev

    Joined:
    Mar 14, 2016
    Posts:
    228
    I'd love to try some 'generic' tool development with Unity / C#, and I noticed the Unity Hub recently got its own menu bar support for macOS.

    Any chance this is something we could get as a feature in Unity, without having to write our own native plugin?

    Basically would be happy with:
    1. Adding an icon and/or text to the menu bar
    2. Being able to update the icon and/or text via code
    3. Receiving onClick events when the icon/text is clicked
    Could see a lot of use-cases for this, especially "duo" apps that support both macOS & iOS. :)

    FWIW, its doable now via a native plugin -- but after sinking my Sunday into native plugin debugging, it'd be awesome to see even just a basic level of support for it as built-in (PS -- C# spoils me & native debugging sucks). =D
     
    Kjaka, 1g0rrr, User340 and 1 other person like this.
  2. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Bonus points for cross-platform support (Mac, PC).
     
    Last edited: Jan 19, 2019
  3. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    I've managed to add NSMenu support to my Unity app, it wasn't too hard. The quickest way to get started is by modifying the MainMenu nib file, add all of the commands there, then write a native plugin to overwrite the target/action for each menu item.
     
  4. Arthur-LVGameDev

    Arthur-LVGameDev

    Joined:
    Mar 14, 2016
    Posts:
    228
    It has been a bit now, but I'd love to scratch this itch for a quick personal weekend project one of these days. =D

    Any chance you'd be willing to share some example code -- specifically the native plugin code?

    I haven't messed with it much since I originally posted this but, at least at the time I first played with this, it was a pain to debug the native stuff, at least compared to the ease of the typical C# feedback loop. :)
     
  5. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    I built my menu in Interface Builder/Xcode, that's the best way because they are usually static. I created an obj-c plugin which contained NSMenu and NSMenuItem code, those are the key classes.

    If you have any specific questions let me know.

    Code (JavaScript):
    1. #import "MenuManager.h"
    2.  
    3. @implementation MenuManager
    4.  
    5. -(id)init
    6. {
    7.     self = [super init];
    8.  
    9.     lastCommand = 0;
    10.  
    11.     [self assignCommand:@"File" item2:@"New Scene" toSelector:@selector(newScene)];
    12.     [self assignCommand:@"File" item2:@"Save" toSelector:@selector(saveScene)];
    13.     [self assignCommand:@"File" item2:@"Save As..." toSelector:@selector(saveProjectAs)];
    14.  
    15.     return self;
    16. }
    17.  
    18. -(void)assignCommand:(NSString*)itemName item2:(NSString*)item2Name toSelector:(SEL)selector
    19. {
    20.     NSMenu *mainMenu = [NSApp mainMenu];
    21.     NSMenuItem *file = [mainMenu itemWithTitle:itemName];
    22.     NSMenu *fileMenu = file.submenu;
    23.     NSMenuItem *newScene = [fileMenu itemWithTitle:item2Name];
    24.     newScene.target = self;
    25.     newScene.action = selector;
    26. }
    27. -(void)setCommandEnabled:(NSString*)itemName item2:(NSString*)item2Name toEnable:(bool)enabled
    28. {
    29.     NSMenu *mainMenu = [NSApp mainMenu];
    30.     NSMenuItem *file = [mainMenu itemWithTitle:itemName];
    31.     NSMenu *fileMenu = file.submenu;
    32.     NSMenuItem *newScene = [fileMenu itemWithTitle:item2Name];
    33.     [newScene setEnabled:enabled];
    34. }
    35.  
    36. -(int)lastCommand
    37. {
    38.     int cmd = lastCommand;
    39.     lastCommand = 0;
    40.     return cmd;
    41. }
    42. -(void)setEnabled:(int)menuCommand enabled:(bool)enabled
    43. {
    44.     if (menuCommand == 1)
    45.         [self setCommandEnabled:@"File" item2:@"New Scene" toEnable:enabled];
    46.     else if (menuCommand == 2)
    47.         [self setCommandEnabled:@"File" item2:@"Save" toEnable:enabled];
    48.     else if (menuCommand == 3)
    49.         [self setCommandEnabled:@"File" item2:@"Save As..." toEnable:enabled];
    50. }
    51.  
    52. -(void)newScene { lastCommand = 1; }
    53. -(void)saveScene { lastCommand = 2; }
    54. -(void)saveProjectAs { lastCommand = 3; }
    55.  
    56. @end
    57.  
     
  6. Kjaka

    Kjaka

    Joined:
    Dec 8, 2015
    Posts:
    18
    I would really like that
     
  7. bbridgesvb

    bbridgesvb

    Joined:
    Jan 4, 2019
    Posts:
    18
    Hey, could you elaborate on how you did this? Is there a way to just drop objective-C files directly in the plugins folder in the project, or do you have to have an entirely separate Xcode bundle project as described in Unity's documentation here? https://docs.unity3d.com/Manual/PluginsForDesktop.html