Checking for GUI focus

Is there a way to check to see if a GUI object (window, text field, etc) has focus? I don’t need to know what item specifically, I just need to know if any GUI object has focus.

I’m looking for a way to do this so that I can determine whether I should be catching Input keypresses for commands or for typing in a text field.

I’ve tried a generic test with GUIUtility.keyboardControl but once a field gets focus, I can’t get it to focus on anything but other windows, which means that my script isn’t processing any commands.

void Update () {
    if (GUIUtility.keyboardControl == 0) {
        // process keystrokes as commands
    }
}

I’d like to avoid this if at all possible as it would be better if the Input simply ignored keystrokes until focus moved away from a text field or other GUI element. I also can’t get it to focus on anything but text fields at the moment either, but that’s another issue…

Any suggestions?

Wow, this is totally my question too. I have in-game chat, and when I click on the chat text field to type, every key also makes it to the InputManager and makes my guy jump and run and flip. If Input.GetButtonDown would just say False when a text box had focus I’d be delighted, but I’d settle for being able to ask if my text box has focus so I can add in a " !TextBoxHasFocus" to my own command handlers.

Oh, and to clarify, GUIUtility.keyboardControl == 0 didn’t work because while it is indeed non-zero while a text entry has focus, it doesn’t go back to zero [Edit: because it won’t give up focus when you click somewhere else].

I was having a similar issues. I found that I could solve my problems with text entry controls by using GUI.DoTextField, which is the method used by the TextField and TextArea. The point is, it accepts an int as the control ID, which you can keep track of using GUIUtility.GetControlID and assigning it to your own local variable.
Also, GUIUtility.keyboardControl can be set to 0 to remove the focus from all text fields, or to assign it to your favorite field.

    //C#
    public int curKeyboardControl;
    private GUIContent myText1 = new GUIContent("Test Field");
    private GUIContent myText2 = new GUIContent("Test Field1");
    private GUIContent myText3 = new GUIContent("Test Field2");
    private bool DoRemoveFocus = false;
    void OnGUI()
    {
        if (DoRemoveFocus)
        {
            GUIUtility.keyboardControl = 0;
            DoRemoveFocus = false;
        }
        curKeyboardControl = GUIUtility.keyboardControl;
        GUI.Label(new Rect(310, 10, 100, 100), "Current\nKeyCtrl: " + curKeyboardControl.ToString(),"box");
        if (GUI.Button(new Rect(410, 10, 100, 100), "Remove Focus")) DoRemoveFocus = true;
        int TextField1ID = GUIUtility.GetControlID(FocusType.Keyboard);
        GUI.DoTextField(new Rect(10, 10, 100, 100), TextField1ID, myText1, true, 200, "TextArea");
        int TextField2ID = GUIUtility.GetControlID(FocusType.Keyboard);
        GUI.DoTextField(new Rect(110, 10, 100, 100), TextField2ID, myText2, true, 200, "TextArea");
        int TextField3ID = GUIUtility.GetControlID(FocusType.Keyboard);
        GUI.DoTextField(new Rect(210, 10, 100, 100), TextField3ID, myText3, true, 200, "TextArea");
    }

btw you must give a GUIContent variable to the DoTextField because its passed by ref, otherwise you can’t edit your text, and then its not really a textfield.

1 Like

How about this for hack-fu:

if( Input.GetMouseButtonDown( 0 )  GUIUtility.hotControl == 0 )
			GUIUtility.keyboardControl = 0;

So that’s “If the mouse is pressed and no widget that accepts input is the target of that press, then clear who has focus.” Now I can click in a text field and type, and then when I click out of the text field it coughs up the focus. Now my game commands can check keyboardControl for non-zero and choose to not do anything while you are typing. I think that applies to the OP’s problem too. Maybe not entirely. Still good fields to know about.

Nice solution. I needed to figure out if a button or textfield in a particular form had focus (to do those nice “Enter Password Here” kind of textfields) which is probably overkill here. For simple GUI, hack-fu rocks.

That looks cool - focus handling in UnityGUI has been giving me quite a bad time recently (I need to be able to focus and unfocus textfields on clicks and key-presses).

Is there any way to use DoTextField with GUILayout? That would solve quite a few issues for me…

Haven’t tested it, but try:

GUI.DoTextField(GUILayoutUtility.GetRect(content, style, options), id, content, multiline, length, style);

The layouting system should pass the correct Rect back, in theory.

I’m curious. How did you determine DoTextField was used by those text controls?

After reading this post, I used Google to search the entire unity3d.com site for “DoTextField” and it only turned up a few forum posts, including this one.

Are there scripts for all the runtime classes that can be examined? If so, where are they?

Hi,

By reflecting the UnityEngine.dll and analyzing the GUI classes there.

Best regards
Shaun

Sorry to revive this old thread, but DoText is now protected. Is there any workaround to this? Should we create a new class inherited from GUI?