I’m working on a Unity form over here for people to sign up for a newsletter: http://coolfone.mobi/EmailSubscribe/ I’d like the user to be able to tab from the Name field to the Email field and vice versa. Anyone know an easy way to do this? Thanks.
Here's pseudo code to get you started...this code would be attached to the input field. Code (CSharp): EventSystem myEventSystem; if (input.GetKey(KeyCode.Tab) { currentInputField = myEventSystem.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown; } This will go to the next UI object in the event system. (If I recall correctly). Sorry that's the best I can do for now.
I don't think you need any code for this... it's what the navigation options are for. I would try those first.
Trouble is that its work with tabs (only arrow keys), so if you want to tab between them you will need to implement it manually.
Oh I see. I rarely use keyboard navigation, so I didn't realize this! It seems like quite an oversight... tab to advance and shift-tab to go back seem like such standards, I'm surprised people aren't screaming about this more. At the very least, somebody ought to file a bug report.
It's actually quite old... https://issuetracker.unity3d.com/issues/pressing-tab-key-does-not-navigate-between-input-controls There were numerous posts, feedback and workarounds (google "unity tab navigation" for some working solutions).
The navigation works on the Input axes. Specifically horizontal and vertical. Just put the tab key in there. It's a little annoying that they choose the same input axes as the default movement ones. So just be aware or you'll find tab also moves you character around.
But actually, you can change these axes in the EventSystem properties (the Standalone Input Module component). So I guess you could define separate axes just for keyboard navigation. Though I suspect that their mixing of horizontal and vertical axes (instead of a single next/previous control axis) might make for a somewhat awkward fit, if you have both horizontal and vertical scrollers in your UI.
Well that does simplify things. Another trick that's worth noting for this stuff is you can define the same axis multiple times in the Input Manager. Unity will check all of them. That way you can assign tab and down and right all to the same axis. Still not sure how you could appply multiple key presses. So Shift+Tab is probably not supportable.
For future readers: Here is a sample of a navigation script I wrote that supports tabbing and reverse tabbing(tab+left or right shift). I attached this script to my EventSystem which was created with the Canvas that houses my login menu. Note: I added a constants class which has constants that refer to the Game Object names of my three login controls. I am sure this isn't the "best" way to do it, but I had a hard time finding any examples so hope this help. Don't forget: (using UnityEngine.EventSystems to reference EventSystem) Code (CSharp): private EventSystem myEventSystem; void Update() { if( (Input.GetKeyDown(KeyCode.Tab) && Input.GetKey(KeyCode.LeftShift)) || (Input.GetKeyDown(KeyCode.Tab) && Input.GetKey(KeyCode.RightShift)) ) { myEventSystem = GetComponent<EventSystem>(); switch (myEventSystem.currentSelectedGameObject.name) { case LoginControls.INPUT_EMAIL: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.BUTTON_LOGIN)); break; case LoginControls.INPUT_PASSWORD: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_EMAIL)); break; case LoginControls.BUTTON_LOGIN: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_PASSWORD)); break; default: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_EMAIL)); Debug.Log("default hit for shift tab"); break; } } else if (Input.GetKeyDown(KeyCode.Tab)) { myEventSystem = GetComponent<EventSystem>(); switch (myEventSystem.currentSelectedGameObject.name) { case LoginControls.INPUT_EMAIL: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_PASSWORD)); break; case LoginControls.INPUT_PASSWORD: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.BUTTON_LOGIN)); break; case LoginControls.BUTTON_LOGIN: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_EMAIL)); break; default: myEventSystem.SetSelectedGameObject(GameObject.Find(LoginControls.INPUT_EMAIL)); Debug.Log("default hit for normal tab"); break; } } } public static class LoginControls { public const string INPUT_EMAIL = "EmailAddressInput"; public const string INPUT_PASSWORD = "PasswordInput"; public const string BUTTON_LOGIN = "LoginButton"; }
here is my code. its in danish, but i have tried to describe what that is doss. its work fine. Code (CSharp): using System.Collections; using System.Collections.Generic; using System; using UnityEngine; using UnityEngine.EventSystems; public class TabScript : MonoBehaviour { public GameObject[] indputvælg; // a array for selecting gameobjekts public GameObject førsteValg; // the first selected gameobjekt public GameObject valgt; // current Selected GameObject public int index; // a int for the array private void Start() { // set the first gameobjekt EventSystem.current.GetComponent<EventSystem>().firstSelectedGameObject = førsteValg; EventSystem.current.GetComponent<EventSystem>().SetSelectedGameObject(førsteValg); print("længde " + indputvælg.Length); } void Update() { // gets the gameobjekt that is chosen valgt = EventSystem.current.GetComponent<EventSystem>().currentSelectedGameObject; if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { print("shiift trykket"); if (Input.GetKeyDown(KeyCode.Tab) || Input.GetKeyDown(KeyCode.Tab)) { print("tab trykket"); hentliste(); index--; if (index >= 0) { print(" 2 " + (indputvælg.Length)); EventSystem.current.GetComponent<EventSystem>().SetSelectedGameObject(indputvælg[index]); } } } else if (Input.GetKeyDown(KeyCode.Tab)) { hentliste(); index++; if (index < (indputvælg.Length)) { print(" 2 " + (indputvælg.Length)); EventSystem.current.GetComponent<EventSystem>().SetSelectedGameObject(indputvælg[index]); } } } // sets the index for the chosen gameobjekt public void hentliste() { for (int i = 0; i < indputvælg.Length; i++) { if (EventSystem.current.GetComponent<EventSystem>().currentSelectedGameObject.name == indputvælg[I].name) { index = i; print("index " + i); } } } } [/I]