Search Unity

How to add shortcut to custom action? (ProBuilder)

Discussion in 'World Building' started by FeastSC2, Nov 6, 2020.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I made this script to add a button to set the pivot the bottom of the mesh.
    It works as it should but I also want to call it with a shortcut.
    How can I do so? I tried to add a MenuAction but it just won't show in Unity's shortcuts manager.

    upload_2020-11-6_2-32-23.png

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.ProBuilder;
    3. using UnityEngine.ProBuilder.MeshOperations;
    4.  
    5. namespace UnityEditor.ProBuilder.Actions
    6. {
    7.     [ProBuilderMenuAction]
    8.     public class SetPivotLowerCenterAction : MenuAction
    9.     {
    10.         public const string Name = "Set Pivot @LowerCenter";
    11.  
    12.         public override ToolbarGroup group
    13.         {
    14.             get { return ToolbarGroup.Object; }
    15.         }
    16.  
    17.         public override Texture2D icon
    18.         {
    19.             get { return null; }
    20.         }
    21.  
    22.         public override TooltipContent tooltip
    23.         {
    24.             get { return k_Tooltip; }
    25.         }
    26.        
    27.         internal const char CMD_SUPER       = '\u2318';
    28.  
    29.         // What to show in the hover tooltip window.  TooltipContent is similar to GUIContent, with the exception
    30.         // that it also includes an optional params[] char list in the constructor to define shortcut keys
    31.         // (ex, CMD_CONTROL, K).
    32.         static readonly TooltipContent k_Tooltip = new TooltipContent(
    33.             Name,
    34.             Name,
    35.             CMD_SUPER, 'K'
    36.         );
    37.  
    38.         // Determines if the action should be enabled or shown as disabled in the menu.
    39.         public override bool enabled
    40.         {
    41.             get { return MeshSelection.selectedObjectCount > 0; }
    42.         }
    43.  
    44.         [MenuItem("MainMenu/Tools/ProBuilder/Object/" + Name)]
    45.         private void Do()
    46.         {
    47.             // Object[] objects = new Object[MeshSelection.selectedObjectCount * 2];
    48.  
    49.             foreach (var mesh in MeshSelection.top)
    50.             {
    51.                 Undo.RegisterCompleteObjectUndo(mesh, Name);
    52.                 Undo.RegisterCompleteObjectUndo(mesh.transform, Name);
    53.             }
    54.            
    55.             foreach (var mesh in MeshSelection.top)
    56.             {
    57.                 // TransformUtility.UnparentChildren(mesh.transform);
    58.                 var bounds = mesh.GetComponent<MeshRenderer>().bounds;
    59.                
    60.                 var pivotPoint = bounds.center;
    61.                 pivotPoint.y = bounds.min.y;
    62.                
    63.                 mesh.SetPivot(pivotPoint);
    64.                 mesh.Optimize();
    65.                 // TransformUtility.ReparentChildren(mesh.transform);
    66.             }
    67.  
    68.             ProBuilderEditor.Refresh();
    69.         }
    70.  
    71.         public override ActionResult DoAction()
    72.         {
    73.             if (MeshSelection.selectedObjectCount < 1)
    74.                 return ActionResult.NoSelection;
    75.  
    76.             // Object[] objects = new Object[MeshSelection.selectedObjectCount * 2];
    77.  
    78.             foreach (var mesh in MeshSelection.top)
    79.             {
    80.                 Undo.RegisterCompleteObjectUndo(mesh, Name);
    81.                 Undo.RegisterCompleteObjectUndo(mesh.transform, Name);
    82.             }
    83.            
    84.             foreach (var mesh in MeshSelection.top)
    85.             {
    86.                 // TransformUtility.UnparentChildren(mesh.transform);
    87.                 var bounds = mesh.GetComponent<MeshRenderer>().bounds;
    88.                
    89.                 var pivotPoint = bounds.center;
    90.                 pivotPoint.y = bounds.min.y;
    91.                
    92.                 mesh.SetPivot(pivotPoint);
    93.                 mesh.Optimize();
    94.                 // TransformUtility.ReparentChildren(mesh.transform);
    95.             }
    96.  
    97.             ProBuilderEditor.Refresh();
    98.  
    99.             return new ActionResult(ActionResult.Status.Success, Name);
    100.         }
    101.     }
    102. }
     
  2. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Still interested to know about this :)
     
  3. antoinebr_unity

    antoinebr_unity

    Unity Technologies

    Joined:
    Nov 16, 2018
    Posts:
    23
    Hi Feast,

    MenuItem and the new Shortcut Attribute, which is probably more what you're looking for, needs to be on a static function to work. I thought we had a public way to get the instance of the action in the toolbar but it's not the case currently. To make it work, you can do something like this in your custom action:

    Code (CSharp):
    1. [Shortcut("MainMenu/Tools/ProBuilder/Object/" + Name", KeyCode.K)]
    2. static void TriggerActionFromShortcut()
    3. {
    4.    new SetPivotLowerCenterAction().DoAction();
    5. }
    Hope this helps
     
    FeastSC2 likes this.
  4. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I just noticed I have this message popping up when I added the shortcut.

    But the shortcut works anyway.

    upload_2020-11-20_15-39-51.png
     
  5. antoinebr_unity

    antoinebr_unity

    Unity Technologies

    Joined:
    Nov 16, 2018
    Posts:
    23
    Did you leave the MenuItem attribute on the Do function?
     
  6. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Code (CSharp):
    1.  
    2. using UnityEditor.ShortcutManagement;
    3. using UnityEngine;
    4. using UnityEngine.ProBuilder;
    5. using UnityEngine.ProBuilder.MeshOperations;
    6.  
    7. namespace UnityEditor.ProBuilder.Actions
    8. {
    9.     [ProBuilderMenuAction]
    10.     public class SetPivotLowerCenterAction : MenuAction
    11.     {
    12.         public const string Name = "Set Pivot @LowerCenter";
    13.         [Shortcut("MainMenu/Tools/ProBuilder/Object/" + Name, KeyCode.V, ShortcutModifiers.Alt | ShortcutModifiers.Shift)]
    14.         static void TriggerActionFromShortcut()
    15.         {
    16.             new SetPivotLowerCenterAction().DoAction();
    17.         }
    18.  
    19.         public override ToolbarGroup group
    20.         {
    21.             get { return ToolbarGroup.Object; }
    22.         }
    23.  
    24.         public override Texture2D icon
    25.         {
    26.             get { return null; }
    27.         }
    28.  
    29.         public override TooltipContent tooltip
    30.         {
    31.             get { return k_Tooltip; }
    32.         }
    33.         // What to show in the hover tooltip window.  TooltipContent is similar to GUIContent, with the exception
    34.         // that it also includes an optional params[] char list in the constructor to define shortcut keys
    35.         // (ex, CMD_CONTROL, K).
    36.         static readonly TooltipContent k_Tooltip = new TooltipContent(
    37.             Name,
    38.             Name
    39.         );
    40.  
    41.         // Determines if the action should be enabled or shown as disabled in the menu.
    42.         public override bool enabled
    43.         {
    44.             get { return MeshSelection.selectedObjectCount > 0; }
    45.         }
    46.  
    47.         [MenuItem("MainMenu/Tools/ProBuilder/Object/" + Name)]
    48.         private void Do()
    49.         {
    50.             // Object[] objects = new Object[MeshSelection.selectedObjectCount * 2];
    51.  
    52.             foreach (var mesh in MeshSelection.top)
    53.             {
    54.                 Undo.RegisterCompleteObjectUndo(mesh, Name);
    55.                 Undo.RegisterCompleteObjectUndo(mesh.transform, Name);
    56.             }
    57.            
    58.             foreach (var mesh in MeshSelection.top)
    59.             {
    60.                 // TransformUtility.UnparentChildren(mesh.transform);
    61.                 var bounds = mesh.GetComponent<MeshRenderer>().bounds;
    62.                
    63.                 var pivotPoint = bounds.center;
    64.                 pivotPoint.y = bounds.min.y;
    65.                
    66.                 mesh.SetPivot(pivotPoint);
    67.                 mesh.Optimize();
    68.                 // TransformUtility.ReparentChildren(mesh.transform);
    69.             }
    70.  
    71.             ProBuilderEditor.Refresh();    
    72.         }
    73.  
    74.         public override ActionResult DoAction()
    75.         {
    76.             if (MeshSelection.selectedObjectCount < 1)
    77.                 return ActionResult.NoSelection;
    78.  
    79.             foreach (var mesh in MeshSelection.top)
    80.             {
    81.                 Undo.RegisterCompleteObjectUndo(mesh, Name);
    82.                 Undo.RegisterCompleteObjectUndo(mesh.transform, Name);
    83.             }
    84.            
    85.             foreach (var mesh in MeshSelection.top)
    86.             {
    87.                 var bounds = mesh.GetComponent<MeshRenderer>().bounds;
    88.                
    89.                 var pivotPoint = bounds.center;
    90.                 pivotPoint.y = bounds.min.y;
    91.                
    92.                 mesh.SetPivot(pivotPoint);
    93.                 mesh.Optimize();
    94.             }
    95.  
    96.             ProBuilderEditor.Refresh();
    97.  
    98.             return new ActionResult(ActionResult.Status.Success, Name);
    99.         }
    100.     }
    101. }
    102.  
    That's the code
     
  7. antoinebr_unity

    antoinebr_unity

    Unity Technologies

    Joined:
    Nov 16, 2018
    Posts:
    23
    You should remove [MenuItem("MainMenu/Tools/ProBuilder/Object/" + Name)] at line 47, it's causing the warning. The menu item attribute cannot be on a non static function so it's currently being skipped and warning you that it won't do anything.
     
    FeastSC2 likes this.
  8. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Indeed, I had forgotten I wrote this, thanks.