Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

[4.6] EditorApplication.modifierKeysChanged, how to find out which key was pressed

Discussion in 'Scripting' started by hexel, Sep 25, 2015.

  1. hexel

    hexel

    Joined:
    Oct 8, 2012
    Posts:
    23
    I'm using this bit of code:

    Code (csharp):
    1.  
    2. [InitializeOnLoad]
    3. public static class VisibilityManager
    4. {
    5.  
    6.    static VisibilityManager()
    7.    {
    8.      EditorApplication.modifierKeysChanged += KeysChanged;
    9.    }
    10.    
    11.    private static void KeysChanged()
    12.    {
    13.      Debug.Log("abcd");
    14.    }
    15. }
    16.  
    This correctly outputs "abcd" to the console whenever a key is pressed. However, how do I find out which key has been pressed/released? I've tried using Input.GetKeyDown, Input.GetKey and Event.current. None of those worked, and Event.current is always null. Is there another way of getting the keys that I don't know about?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    21,405
    I see this too. Here's my codelet:

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [InitializeOnLoad]
    6. public static class VisibilityManager
    7. {
    8.     static int counter;
    9.  
    10.     static VisibilityManager()
    11.     {
    12.         EditorApplication.modifierKeysChanged += KeysChanged;
    13.     }
    14.  
    15.     private static void KeysChanged()
    16.     {
    17.         counter++;
    18.         Debug.Log(
    19.             counter.ToString () +
    20.             "   Lalt:" + Input.GetKey (KeyCode.LeftAlt) +
    21.             "   Ralt:" + Input.GetKey (KeyCode.RightAlt) +
    22.             "");
    23.     }
    24. }
    Both ALTs are always false, running on a Mac.
     
  3. hexel

    hexel

    Joined:
    Oct 8, 2012
    Posts:
    23
    Bump. A related question, I haven't been able to detect input in EditorApplication.update either. Is it possible in either function?
     
  4. hexel

    hexel

    Joined:
    Oct 8, 2012
    Posts:
    23
    Bump.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    21,405
    Try maybe throwing your question over in the Editor and General Help area... they might do better. You can put my code in too, I don't mind, whatever gets you a good answer. It seems like a bug here...
     
  6. NoUJoe

    NoUJoe

    Joined:
    Mar 7, 2014
    Posts:
    30
    Not the cleanest as it requires using reflection, but this should get you what you want.

    Code (CSharp):
    1. [InitializeOnLoadMethod]
    2.     static void EditorInit ()
    3.     {
    4.         System.Reflection.FieldInfo info = typeof (EditorApplication).GetField ("globalEventHandler", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
    5.  
    6.         EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue (null);
    7.  
    8.         value += EditorGlobalKeyPress;
    9.  
    10.         info.SetValue (null, value);
    11.     }
    12.  
    13.  
    14.     static void EditorGlobalKeyPress ()
    15.     {
    16.         Debug.Log ("KEY CHANGE " + Event.current.keyCode);
    17.     }
    EditorGlobalKeyPress () will be called every time a key is pressed in the editor. During this callback, Event.current will be valid so you can read Event.current.KeyCode and go from there. You do not have to be focused on any particular window/GUI for it to work. This is how Unity internally handle Hot Keys for changing tools (move, rotate, scale etc).

    Features like frame selected, duplicate, copy paste etc that have hotkeys are all handled by https://docs.unity3d.com/ScriptReference/MenuItem.html, and shortcuts like 2D mode, the first person controls in scene view, maximise window (shift + space, i didnt know about this one until the other day, its a good one!) are all handled per EditorWindow in the OnGUI callbacks.

    So the callback we're hooking into for this "global" event is a delegate; EditorApplication.globalEventHandler, but it's marked as internal so we have to use reflection to get and set it. As far as I can tell (and I've looked into it myself a few times now) this is the only way to get a "global editor key press" and it's bloody internal... Honestly they should just make it public, the implementation is nothing complex, they wouldn't need to change anything to make it safe to use publicly, you only get KeyUp and KeyDown events during the callback so you can't mess anything up by trying to draw GUI elements.

    Hope this helps anyone who may stumble here needing to know how to do this!
     
    Cobo3 and SarfaraazAlladin like this.
  7. SarfaraazAlladin

    SarfaraazAlladin

    Joined:
    Dec 20, 2013
    Posts:
    279
    This is awesome! Tried it out and it works like a charm, other than the shift keys which is a little curious.
     
    NoUJoe likes this.
  8. Bill-Sansky

    Bill-Sansky

    Joined:
    Oct 2, 2016
    Posts:
    74
    Hi!
    I just came across that answer, pretty cool!
    I am also wondering why the shift key isn't working: any idea?
     
  9. Bill-Sansky

    Bill-Sansky

    Joined:
    Oct 2, 2016
    Posts:
    74
    Found the solution for anyone coming here later:

    Event.current.shift will be true if shift is pressed while any other key is also pressed: in other words the even does not get called when shift alone is pressed, but you can get the information when any other key is.
     
    Vedran_M and SarfaraazAlladin like this.
unityunity