Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by jmparavicini · May 06, 2016 at 09:47 AM · editoreventhotkeys

Custom hot keys manager

Hi everyone So i wanted to make a little editor window where you can set up hotkeys and execute any functions you want using UnityEvents. Well i didn't really get far, i have the EditorWindow that seems to work fine but then my first problem is that first of all it only "works" when i have only one KeyCode. The second problem is that I can't use UnityEvent.Invoke() in edit mode, I tried pretty much everything to make it work but it doesn't, I've set in the unity event to execute in edit mode and at runtime but that didn't solve it either.

Well here is my code:

 using UnityEngine;
 using UnityEngine.Events;
 using UnityEditor;
 using System.Collections;
 using System.Collections.Generic;
 
 public class ShortcutManager : EditorWindow
 {
     [MenuItem ("Manager/Short Cuts")]
     public static void Init ()
     {
         ShortcutManager window = (ShortcutManager)EditorWindow.GetWindow (typeof(ShortcutManager));
         window.Show ();
     }
 
     [System.Serializable]
     public class Shortcut
     {
         public List<KeyCode> m_shortCut;
         public UnityEvent m_event = new UnityEvent ();
     };
 
     private Vector2 scrollPos;
 
     public List<Shortcut> m_shortCuts;
 
     private Event currentEvent;
 
     void OnGUI ()
     {
         scrollPos = EditorGUILayout.BeginScrollView (scrollPos);
 
         EditorGUILayout.LabelField ("Global shortcut manager", EditorStyles.boldLabel);
         EditorGUILayout.Space ();
 
         SerializedObject so = new SerializedObject (this);
         SerializedProperty m_shortCutProperty = so.FindProperty ("m_shortCuts");
         EditorGUILayout.PropertyField (m_shortCutProperty, true);
         so.ApplyModifiedProperties ();
 
         if (GUILayout.Button ("Invoke"))
             m_shortCuts [0].m_event.Invoke ();
 
         EditorGUILayout.EndScrollView ();
 
         currentEvent = Event.current;
     }
 
     void Update ()
     {
         CheckShortCuts ();
         if (Input.GetKeyDown (KeyCode.A))
             m_shortCuts [0].m_event.Invoke ();
     }
 
     void CheckShortCuts ()
     {
         if (currentEvent == null || !currentEvent.isKey || currentEvent.type != EventType.KeyDown)
             return;
 
         foreach (Shortcut shortCut in m_shortCuts)
         {
             for (int count = 0; count < shortCut.m_shortCut.Count; ++count)
             {
                 if (!((int)currentEvent.character == (int)shortCut.m_shortCut [count]))
                     break;
                 
                 if (count == shortCut.m_shortCut.Count - 1)
                 {
                     Debug.Log ("Yay?");
                     shortCut.m_event.Invoke ();
                 }
             }
         }
     }
 }



Well for the first problem i know it is embarrassingly bad but i can't figure it out how to do it better, on lines 63-66 i do the check for all the key codes as you can see i use a foreach loop and check if every key is pressed on after the other but it didn't work, it only does if there is only 1 key code in the list.

For the second problem i did even a test with the button called Invoke that should invoke the 1 item of the shortCuts list. I'll post a picture of the Unity event in the Editorwindow, it is pointing to a public function that just debugs a string, but there I can't figure out how to make it work in edit mode, i sure hope it's possible D:.

Well thanks in advance and any other suggestions are warmly welcome,

-Jorge

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · May 06, 2016 at 11:22 AM

You have several problems here. First of all forget about the Input class when it comes to editor scripts. The Input class only works at runtime.

Next thing is OnGUI does work, but it's context specific. That means your editor windows OnGUI method does only process events when the window has the keyboard focus. It's not clear how your hotkeys should behave exactly. Also at the moment your hotkey is restricted to only a single key. For hotkey you usually include optional modifier key combination (CTRL, ALT, SHIFT) otherwise (if you have application wide or system wide hotkeys) you would trigger the hotkey at times where you don't want it (for example when you enter text in a text field).

Your use of the Event class is just strange. The Event class should only be used inside OnGUI. Storing the Event for later use makes not much sense. Do the handling inside OnGUI. OnGUI might be called several times in a row with different events. At the moment you only get the "last" event that OnGUI had processed.

You also never invalidate "currentEvent" in some way, so as long as "currentEvent" contains a valid key you contantly execute your method until OnGUI processes a new, different event.

It seems you want to check multiple keys at once for one hotkey. That's actually quite difficult because OnGUI and Event work on "events" not on "states". So if you press key1 OnGUI would recognise that key if you later press key2 it again recognises that key but doesn't know about key1 anymore since you didn't save the key state. At runtime the Input class provides you with key states, however there's nothing built-in that does this in the editor (except for the modifier keys).

So some suggestions to solve those problems:

  • To get the Events when the SceneView is in focus you might want to subscribe a callback to SceneView.onSceneGUIDelegate. The whole usage of Unity's Event system might give you more trouble as there's not a reliable way to get all Events in Unity independent from which window has the focus. You could use an approach as mentioned in this answer, but it's platform dependent and only works on Windows. You would need an alternative on other platforms.

  • You need to keep track of the key state somewhere. The easiest solution is to create a boolean array which has an element for every KeyCode. Whenever you get a KeyDown event you set the appropriate boolean to true, when you get a KeyUp event you set it back to false. That way you can track the state of all keys at the same time. Keep in mind that key ghosting can get you in trouble.

  • Most hotkeys should do something when the SceneView is in focus, so the onSceneGUIDelegate usually is enough. However if you want system wide hotkey support you have to look out for native OS solutions.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jmparavicini · May 08, 2016 at 01:00 AM 0
Share

First of all thanks for the reply and im sorry not to answer before. Well i managed to get the keys to work by making a scriptableObject which has a list of all pressed down buttons. So with list.Contains i can check if the buttons are pressed or not, is this a good way to tackle the problem? I mean for performance?

But i still have the second problem, I can't call UnityEvent.Invoke and i'm honestly not sure how to make it work :/

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

47 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Get mouse position in Editor based on screen coordinates 1 Answer

Mouse click in edit mode. ✱✺✸❁ 1 Answer

The type or namespace name 'EventSystems' does not exist in the namespace 'UnityEngine' 0 Answers

UnityEvent draws debug variables in the inspector 0 Answers

Editor layout hotkeys? 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges