[Unity 5] GUIUtility.GetControlID Equivalent for Joysticks and Controllers?

Hey, I have a custom editor control to allow me to edit default keyboard controls, but I am wondering if there’s a way to adapt this to allow joystick and controller buttons, too.

I don’t need to worry about the actual axis sticks, I’m going to hardcode those, it’s just the actual buttons I need a bit of help with.

I’ve noticed that many applications (such as Xinmapper, Inputmapper and Xinput) are able to detect which button you’ve pressed on-the-fly, in a similar way to the code I have for keyboards, but I cannot work out how exactly this is done.

The code I am currently using is below, in which I can use something like this to get an in-editor-window button that allows me to press a key to assign the KeyCode declaration easily:

moveForward = KeyCodeFieldLayout(moveForward);

I just can’t work out how to get this working on controllers.
Basically, I’m not using the input system at all, I’m building my own as I can have only the controls usable in the system visible and set up independently of any Unity built-in features which is easier for me.

public static KeyCode KeyCodeField(Rect controlRect, KeyCode keyCode)
    {
        int controlID = GUIUtility.GetControlID(FocusType.Keyboard);

        KeyCode retVal = keyCode;

        Event evt = Event.current;

        switch (evt.GetTypeForControl(controlID))
        {
            case EventType.Repaint:
                {
                    //GUIStyle style = GUI.skin.GetStyle("TextField");
                    //GUIStyle style = EditorStyles.toolbar;
                    GUIStyle style = new GUIStyle("ShurikenModuleTitle");
                    style.font = new GUIStyle(EditorStyles.label).font;
                    style.fixedHeight = 20;
                    style.alignment = TextAnchor.MiddleCenter;
                    style.contentOffset = new Vector2(0f, -2f);
                    style.margin = new RectOffset(3, 2, 0, 1);

                    if (style == GUIStyle.none)
                    {
                        //Debug.Log("GUI Style not found");
                    }

                    if (GUIUtility.keyboardControl == controlID)
                    {
                        style.Draw(controlRect, new GUIContent("Press a key"), controlID);
                    }
                    else
                    {
                        style.Draw(controlRect, new GUIContent(keyCode.ToString()), controlID);
                    }
                    //GUI.backgroundColor = defaultColor;
                    break;
                }
            case EventType.MouseDown:
                {
                    if (controlRect.Contains(Event.current.mousePosition) && Event.current.button == 0 && GUIUtility.hotControl == 0)
                    {
                        //Debug.Log("mouse down event, control id: " + controlID + ", hot control: " + GUIUtility.hotControl);
                        GUIUtility.hotControl = controlID;
                        GUIUtility.keyboardControl = controlID;
                        evt.Use();
                    }
                    break;
                }
            case EventType.MouseUp:
                {
                    if (GUIUtility.hotControl == controlID)
                    {
                        GUIUtility.hotControl = 0;
                        evt.Use();
                    }
                    break;

                }
            case EventType.KeyDown:
                {
                    //Debug.Log("key down, control id: " + controlID + ", hot control: " + GUIUtility.hotControl);
                    if (GUIUtility.keyboardControl == controlID)
                    {
                        //Debug.Log("hotcontrol");
                        retVal = Event.current.keyCode;
                        GUIUtility.hotControl = 0;
                        GUIUtility.keyboardControl = 0;
                        evt.Use();
                    }
                    break;
                }
            case EventType.KeyUp:
                {
                    break;
                }
        }

        if (controlRect.Contains(Event.current.mousePosition))
        {
            EditorGUIUtility.AddCursorRect(controlRect, MouseCursor.Link);
        }

        return retVal;
    }

    public static KeyCode KeyCodeFieldLayout(KeyCode keyCode)
    {
        return KeyCodeField(EditorGUILayout.GetControlRect(), keyCode);
    }

Anyone know how I can adapt this to work with/catch controller buttons in-editor?

You’re using the event system of the old IMGUI (as opposed to Unity UI and now UI Toolkit), which only supports keyboard/mouse and very likely will never support anything else. Unity UI and UI Toolkit (I think) support gamepads using the InputSystemUIInputModule, which means that only works at runtime, not at edit time.

So your only option is to use the Input System directly. IMGUI is basically end-of-life and won’t be changed to support gamepads, while UI Toolkit might get edit-time support for gamepads via the Input System at some point. But you can freely use only the parts of the Input System you need (some of it also isn’t available at edit-time), I don’t see how that should prevent you from rolling your on system on top of it.

Ok, what would I do if I ported this over to the newer versions of Unity? What system (outside of the input system) will allow me to grab pressed gamepad controls in editor?

There’s only the Input System. It seems like Unity wants to use it for all non-Keyboard/Mouse input, in the editor and at runtime. That’s why I mentioned that the newest UI system, UI Toolkit, is also using the Input System for gamepad input.