Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Shortcut Manager Feature Preview

Discussion in 'Editor Workflows' started by smcclelland, Sep 11, 2018.

  1. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    1,212
    Actually, with a bit of trial (and a lot of error) the [Shortcut(..)] attribute on a static method worked fine with an editorwindow. It wasn't obvious at first that I could just set all the keycodes to none and let the end user of our tools configure them in the shortcut manager. I thought I'd need to create the custom categories myself in code.

    Some more detail, like an example in the doco might help others.
     
    MariaAngelovaPD and awesomedata like this.
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,335
    I totally understand why some shortcuts needs to not be activated during play mode, but generally this is bad. This should be something that's selected on a shortcut-by-shortcut basis.

    I asked in one of the other threads, but never got a reply - what's meant by "This is to guarantee old behavior"? If some command should not run in some case, it's the job of that command to prevent that, it shouldn't be a situation of "well some command doesn't support this, so now we have to block it from everyone"

    We're not going to be able to use this feature for a large chunk of our commands because of this, so we're back to using non-rebindable [MenuItem] shortcuts.
     
  3. jonathans42

    jonathans42

    Unity Technologies

    Joined:
    Jan 25, 2018
    Posts:
    184
    I hear you. I think we should revisit that decision. I would suggestion that we have a specific shortcut profile when in play mode, that binds less shortcuts, but still allow the user to rebind any of the shortcuts. Then, when you exit playmode, we switch back to the editmode shortcut profile automatically.
     
    Last edited: Aug 7, 2019
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,335
    Ideally, it should just be an option on the Shortcut-attribute. Maybe another [Flags] enum that could specify when the attribute was active?

    I'm suggesting that because having shortcuts that are only available in play mode would be nice for editor-only developer features that you want to make super-sure is not a part of any build.


    While you're at it, could you document the "context" parameter? "Optional shortcut context type" isn't very much of an explanation. Can you give it the type of some editor window and have it only be active if in the context of that window type, or...?
     
  5. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    1,212
    As some general feedback, the new shortcut manager is a great feature, which as a editor tool developer, really helps improve the customer experience.

    Pros
    Keyboard layout with Unassigned, Assigned and Global keys
    Keyboard layout tooltips
    Categories that are auto-populated from the Shortcut attributes
    Conflict management
    Context sensitive

    Cons
    Functionality; None found so far :)
    No example code in API reference docs (what is obvious to Unity devs not so obvious to the rest of us)
     
  6. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    846
  7. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    846
    An even better idea would be a "Bind in Playmode" attribute.


    Some tool developers would like to ensure some shortcuts work in PlayMode, while others (or even the same shortcuts) should not be available (or should operate differently) in PlayMode.

    I can see this being _very_ handy for tool developers (like me) to let users modify game data using shortcut tools while the game is running.


    Just so much useful there.
     
    Lars-Steenhoff likes this.
  8. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    539
    I'm using the ShortcutManager a lot for our inhouse tools, but I keep being annoyed by the fact that I need to create a static method for each individual shortcut even though a lot of the functionality could be refactored into using one or two parameters. Here's an example:

    Code (CSharp):
    1. [Shortcut("GridMoveTool/RotateRight", typeof(SceneView), KeyCode.Period, ShortcutModifiers.Shift)]
    2. private static void RotateRight()
    3. {
    4.     RotateHelper(Vector3.forward, -90f);
    5. }
    6.  
    7. [Shortcut("GridMoveTool/RotateLeft", typeof(SceneView), KeyCode.Comma, ShortcutModifiers.Shift)]
    8. private static void RotateLeft()
    9. {
    10.     RotateHelper(Vector3.forward, 90f);
    11. }
    12.  
    13. [Shortcut("GridMoveTool/FlipVertical", typeof(SceneView), KeyCode.Y, ShortcutModifiers.Shift)]
    14. private static void FlipVertical()
    15. {
    16.     RotateHelper(Vector3.right, 180f);
    17. }
    18.  
    19. [Shortcut("GridMoveTool/FlipHorizontal", typeof(SceneView), KeyCode.X, ShortcutModifiers.Shift)]
    20. private static void FlipHorizontal()
    21. {
    22.     RotateHelper(Vector3.up, 180f);
    23. }
    24.  
    25. private static void RotateHelper(Vector3 axis, float angle)
    26. {
    27.     if (instance == null)
    28.         return;
    29.  
    30.     var go = instance.target as GameObject;
    31.  
    32.     if (go == null)
    33.         return;
    34.  
    35.     Renderer renderer = go.GetComponent<Renderer>();
    36.  
    37.     Vector3 position;
    38.  
    39.     if (renderer != null)
    40.         position = renderer.bounds.center;
    41.     else
    42.         position = go.transform.position;
    43.  
    44.     instance.RotateTarget(position, axis, angle);
    45. }
    46.  
    47.  
    48. private void RotateTarget(Vector3 pivot, Vector3 axis, float angle)
    49. {
    50.     GameObject go = target as GameObject;
    51.     Undo.RecordObject(go.transform, "Rotate Transform");
    52.     go.transform.RotateAround(pivot, axis, angle);
    53. }
    This works fine, but could be shortened and be more readable if the Shortcut attribute would allow users to pass an argument of type object and use multiple attributes on a single method. Or, even better, similar to NUnit and co define a data source, which would be an IEnumerable that returns arbitrary data. All in all I think that the Shortcut attribute could copy some ideas from testing frameworks.

    That's simply an idea, other than that I'm very happy about how the ShortcutManager system works! :)
     
    awesomedata and Lars-Steenhoff like this.
  9. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    42
    So today I was hoping to rebind some of the Animation Clip Editor's hotkeys (specifically the "," and "." next/prev keyframe keys) to something easier to reach with my left hand ("z" and "x"). But I can't because "z" and "x" are setup as Global keys (along with Q/W/E/R/T/Y) because I guess everything in the top Toolbar is that way?

    It's never been clear to me as to why these are global and not part of the actual Scene view? They don't apply to most/any other windows like Game or Animator or Animation, yet they prevent several useful hotkeys from being used by other windows. Is there a plan to eventually make these part of the scene view? (or is there a better forum to ask this in?)
     
    awesomedata and Lars-Steenhoff like this.
  10. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    354
  11. ReptileDev

    ReptileDev

    Joined:
    Aug 6, 2018
    Posts:
    2
    Hello,

    I'm using the Shortcut Manager in combination with the EditorTool class, and found some issues when trying to detect if a modifier key is held:

    Code (CSharp):
    1. public class MyTool : EditorTool
    2. {
    3.     static KeyCombination shortcut; // Set when MyTool becomes the active tool
    4.  
    5.     public override void OnToolGUI( EditorWindow window )
    6.     {
    7.         // Check if we are holding the shortcut keys down
    8.         if( Event.current.modifiers == shortcut.modifiers ) //NOTE: this won't compile
    9.         {
    10.             // do stuff here
    11.         }
    12.     }
    13. }
    As you can see the check at line 8 can not be done, since Event.modifiers and KeyCombination.modifiers are two different enums.

    Unfortunately they can not be casted to int either since, since their order does not match:

    Code (CSharp):
    1. public enum EventModifiers
    2. {
    3.         None = 0,
    4.         Shift = 1,
    5.         Control = 2,
    6.         Alt = 4,
    7.         Command = 8,
    8.         Numeric = 16,
    9.         CapsLock = 32,
    10.         FunctionKey = 64
    11. }  
    12.  
    13. public enum ShortcutModifiers
    14. {
    15.         None = 0,
    16.         Alt = 1,
    17.         Action = 2,
    18.         Shift = 4
    19. }
    Am I approaching this wrong? If so what's the correct way?
     
  12. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    1,212
    If you want to check for modifier keys, you could just check the current event.

    Code (CSharp):
    1. bool isCtrlKey = currentEvent.control;
    2. bool isShiftKey = currentEvent.shift;
    3. bool isAltKey = currentEvent.alt;