How to disable movement keys when typing into input box.

I’ve searched around and tried many times but I am stuck.
I have an input box.

GUI.SetNextControlName ("inputbox");
userInput = GUI.TextField (new Rect (25, 25, 100, 30), userInput);

I focus on the input box when the user presses ‘tab’.
Now in the built in game player this works and I can type into the input box fine and it does not affect the player.
However when I build the game despite being focused on the input box the first person controller moves around and jumps when I type into the input box.

How can I stop the player moving when typing into the input box please ?

Thank you.

It is 2019 and I still haven’t discovered the answer. Something that you would expect to happen automatically yet it doesn’t.

Disable the player controller first. Then enable it when you exit the input screen.

2 Likes

This works in the editor because in the editor the game’s Input manager does not receive messages unless the game window is focused. So when the textbox has focus, the game window does not. (or at least I bet that’s what is going on)

Usually for such functionality you need to setup this behaviour yourself.

Personally I don’t use the UnityEngine.Input class directly and instead have an ‘InputDevice’ class for each individual input device in my game (for each player). I also have an ‘enabled’ property on it that I can turn on/off. I’d set it to disabled when I want the user to do inputs like this.

If you don’t have this, and you just use the global ‘Input’ class, you could just have a global bool that says if it’s on/off and you check that before reading user input.

2 Likes

I use a singleton behavior like this to keep track of whether regular keyboard input should be allowed:

void OnEnable()
{
    system = EventSystem.current;
}

void Update()
{
    bool allow = true;
    if (system == null)
    {
        system = EventSystem.current;
        if (system == null) return;
    }
    GameObject currentObject = system.currentSelectedGameObject;
    if (currentObject != null)
    {
        InputField inputField = currentObject.GetComponent<InputField>();
        if (inputField != null)
        {
            if (inputField.isFocused)
            {
                allow = false;
            }
        }
        else
        {
            TMP_InputField tmpInput = currentObject.GetComponent<TMP_InputField>();
            if (tmpInput != null)
            {
                if (tmpInput.isFocused)
                {
                    allow = false;
                }
            }
        }
    }
    // Enable or disable input based on value of "allow"
}

Not necessarily. Such things can be considered use case specific and it would certainly cause more trouble to find workarounds to undo this, than leaving this up to the developer and his specifics needs. Of course they could add some sort of configuration whether that input field should “eat” that event, but most of the time, you’ll find that insufficient.

In its most simplistic form, you could keep track of whether the user should control the player, or type texts into input fields. For instance, an easy place to make such decisions can be a listener (or a polling mechamisn - depends on the input system / components that you use) that just waits for input-fields to receive the interaction focus. Once this happened, you can notify other systems that you no longer want to control the player with the subsequent inputs, until the focus is lost.

That might already be enough, more complex solutions could be built onto a system that use context / filter -based input handlers, which you can activate / deactivate, i.e. they either run seperately or at the same time. Based on these, one could allow to re-direct input to only those subsystems and entities that are meant to receive the current events.

For example, assume your application binds the character controls to an instance of an input handler, it also binds menu navigation to another instance of such an input handler, and so on…

The only thing you’d ever need to do is disallowing the propragation of input events for a certain input handler, i.e. it’ll swallow the events that were dispatched - the systems that were bound to that handler wouldn’t even notice anything about it, and they honestly don’t need to care about it most of the time. In other words, you wouldn’t even need to tell your character controller to stop reacting, because that responsibility would then reside in a completely different place.

Those are just 2 of many concepts though.

Just disable the gameObject’s movement script when ever you do an action that needs typing and when you finish typing or press enter or close the opened window etc… re-enable the script.

just tried this one-liner (inside Update loop for movement) and seems to work for my use case:

if (EventSystem.current.currentSelectedGameObject != null) return;
3 Likes

Life saver. Thank u!

Here’s another option that checks to see if the currently selected object is an Input Field First.

public static bool IsSelectedObjectInputField()
    {
        if (EventSystem.current.currentSelectedGameObject != null)
        {
            if (EventSystem.current.currentSelectedGameObject.GetComponent<TMPro.TMP_InputField>() != null) return true;
            if (EventSystem.current.currentSelectedGameObject.GetComponent<UnityEngine.UI.InputField>() != null) return true;
        }
        return false;
    }