Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug ShortcutManager wrong Event.current.mouse.position from Shortcut attribute

Discussion in 'Package Manager' started by OBJVISION, Dec 27, 2022.

  1. OBJVISION

    OBJVISION

    Joined:
    Oct 5, 2020
    Posts:
    7
    Let me explain better than the horrific title.
    The following Editor class log on console the current mouse position .
    The problem is that the same function is called creating a shortcut using the Shortcut attribute, and the result is that if i press the key, the two pieces of code print different mouse positions.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.ShortcutManagement;
    4.  
    5. [CustomEditor(typeof(TestScript), true)]
    6. public class TestScriptEditor : Editor
    7. {
    8.     protected void OnSceneGUI()
    9.     {
    10.         Event e = Event.current;
    11.         switch (e.type)
    12.         {
    13.             case EventType.KeyDown:
    14.             {
    15.                 if (Event.current.keyCode == (KeyCode.Alpha0))
    16.                     Debug.Log("mousepos OnSceneGUI= " + Event.current.mousePosition.ToString());
    17.                 //e.Use();
    18.                 break;
    19.             }
    20.         }
    21.     }
    22.  
    23.     [Shortcut("test/shortcutTest2", KeyCode.Alpha0)]
    24.     public static void ToolWindowToggleAlternateMode(ShortcutArguments args)
    25.     {
    26.         Vector2 mousePos = Event.current.mousePosition;
    27.         Debug.Log("mousepos from SHORTCUT MANAGER= " + Event.current.mousePosition.ToString());
    28.     }
    29. }
    30.  
    Seems that the one called as shortcut is getting the wrong mouse position, but it is the one that i need to use, is that any way to fix this?
    Or would be better if there is any way to bind shortcuts and actions using the ShortcutManager.instance

    I attach two screenshot:
    - the one is the result of 3 keydown with mouse in different position, as you can see the one called on shortcut always has the same difference.
    - and the other is Event.current state debugged in visual studio, the left one is called in OnSceneGUI and the right one is called from shortcut.


    Thank you in advance.
     

    Attached Files:

  2. TomasKucinskas

    TomasKucinskas

    Unity Technologies

    Joined:
    Dec 20, 2017
    Posts:
    60
    Hi @OBJVISION! I played around with your script and managed to get a consistent mouse position like this:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.ShortcutManagement;
    4. using UnityEngine.UIElements;
    5.  
    6. public class TestScript : MonoBehaviour { }
    7.  
    8. [CustomEditor(typeof(TestScript), true)]
    9. public class TestScriptEditor : Editor
    10. {
    11.     protected void OnSceneGUI()
    12.     {
    13.         switch (Event.current.type)
    14.         {
    15.             case EventType.KeyDown:
    16.             {
    17.                 if (Event.current.keyCode != (KeyCode.Alpha0))
    18.                     return;
    19.  
    20.                 var sceneView = SceneView.currentDrawingSceneView;
    21.                 var mousePos = Event.current.mousePosition;
    22.  
    23.                 if (sceneView != null)
    24.                     mousePos += sceneView.rootVisualElement.Q("overlay-window-root").worldBound.position;
    25.  
    26.                 Debug.Log("mousepos OnSceneGUI= " + mousePos);
    27.                 break;
    28.             }
    29.         }
    30.     }
    31.  
    32.     [Shortcut("test/shortcutTest2", KeyCode.Alpha0)]
    33.     public static void ToolWindowToggleAlternateMode(ShortcutArguments args)
    34.     {
    35.         Debug.Log("mousepos from SHORTCUT MANAGER= " + Event.current.mousePosition);
    36.     }
    37. }
    38.  
    It seems that OnSceneGUI does some extra preparations for event info knowing that you will be primarily working with SceneView while ShortcutManager does not do that. Specifically, the SceneView window title bar and docked overlays are subtracted from mouse coordinates.

    We can make the results of the two shortcut methods match by adding the scene view viewport offset in the editor window to the mouse coordinates in the OnSceneGUI shortcut version.
     
  3. OBJVISION

    OBJVISION

    Joined:
    Oct 5, 2020
    Posts:
    7

    Hi Tomas, thank you for helping me.

    you give me a good solution but let me extend my problem.

    I have a Shortcut manager Class Like this:





    Code (CSharp):
    1.  
    2.  
    3. [ExecuteInEditMode, UnityEditor.InitializeOnLoad]
    4.  
    5. public class MyShortcutManager : MonoBehaviour{
    6.  
    7. public static MyShortcutManager Instance;
    8. private Dictionary<string, Dictionary<KeyCode keyCode, UnityEvent>> m_shortcutsActionsDictionary;
    9.  
    10. void AddListener(KeyCode keyCode, UnityEvent event){// bind action to key and put in dictionary}
    11.  
    12. void TriggerEvent(){// get and call UnityEvent from dictionary}
    13.  
    14. [Shortcut("test/TriggerW", KeyCode.W)]
    15.     public static void TriggerW(ShortcutArguments args)
    16.     {
    17.       TriggerEvent(args, KeyCode.W);
    18.     }
    19.  
    20. [Shortcut("test/TriggerA", KeyCode.A)]
    21.     public static void TriggerW(ShortcutArguments args)
    22.     {
    23.       TriggerEvent(args, KeyCode.A);
    24.     }
    25. }
    26.  
    27.  


    NB: I need to use shortcutManager to create and switch profiles between windows ad because it is a constraint of the task)

    This is another simplification but just for this example could work.

    So i attach this to a object and then other teams member register my actions from other script to keyPress , the actions can be use a function that is used also onGui and get the mouse position to find click point, i cant know if they are calling that from onGui or ShortcutManager and i cannot hardcode some variables to know where i came from.

    I think the big problem is the method used to create shortcut (with attribute) seems to lose context. If i can create shortcut by a simple shortcut manager function call maybe i can avoid context switch.

    Do you know if there is a way to bind an action to a shortcut without the use of Attributes? Maybe something Like ShortcutManager.bindAction(shortcut, action).

    I need to find a solution to adapt my shortcut manager to the rest of the program.
     
  4. TomasKucinskas

    TomasKucinskas

    Unity Technologies

    Joined:
    Dec 20, 2017
    Posts:
    60
    Well if you need to change shortcut behavior between windows, then contextual shortcuts that specify the window type the shortcut will be invoked on seems like the way to go (That is if you need only specific hardcoded windows to be able to execute shortcuts). If users can bind actions for any window, you should make it a global shortcut, not specify any window type, and have one shortcut per key combination.

    On top of that, as I understand, you need users to be able to subscribe their own functionality for those shortcuts. I would try making a scriptable object that houses a dictionary where keys are window type name strings and values are UnityEvents. It similar to how some assets do settings (For example DOTween).

    When executing a shortcut you check 'EditorWindow.focusedWindow.GetType().Name' to get your dictionary key and then just invoke the event that you receive.

    Does that make sense or is it not exactly what you want?

    One hard limitation that I want to make clear is that you can't dynamically create new shortcuts(while executing a script). It is a design limitation that allowed us to make ShortcutManager window enumerate all registered shortcuts(by searching for attributes) and provide a nice UI and rebinding capabilities for it. So if you want fully dynamic shortcuts or assign key codes via a script, then I'd ditch ShortcutManager and try implementing such system in OnGUI knowing that users won't be able to rebind those shortcuts via ShortcutManager window.