I try this in unity
public class InputsNextFocusBehaviour : MonoBehaviour
{
public InputField _input1;
public InputField _input2;
public InputField _input3;
public InputField _input4;
public InputField _input5;
// Use this for initialization
private void Start()
{
_input1.onValueChanged.AddListener(arg0 =>
{
if (arg0.Length > 0)
{
_input2.Select();
}
});
_input2.onValueChanged.AddListener(arg0 =>
{
if (arg0.Length > 0)
{
_input3.Select();
}
});
_input3.onValueChanged.AddListener(arg0 =>
{
if (arg0.Length > 0)
{
_input4.Select();
}
});
_input4.onValueChanged.AddListener(arg0 =>
{
if (arg0.Length > 0)
{
_input5.Select();
}
});
_input5.onValueChanged.AddListener(arg0 =>
{
if (arg0.Length > 0)
{
Debug.Log("you are the best: the text input is" +
_input1.text + _input2.text + _input3.text + _input4.text + _input5.text);
}
});
}
}
basically when write a letter in the first inputField, select the next one, writes in the other an select next, until the last one.
In windows works ok, but in android around 3rd input, the touchscreenkeyboard does not appear anymore.
is there any way to solve this issue? or is there another alternative that works on windows and android? thanks and sorry for my english
This question has been bothering me for a long time.
Please do not switch the InputField component,use only one InputField component,change the inputfield.textcomponent.
But I also have confusion,some phone models pop up with minimal input.
Related
Im new in developing so need some help for my game!
On my game I have 2 buttons one is "Play" and other "Level Select"
I stuck at the "Play" button, need to make a script that is always loading the highest level that is unlocked, not current but highest.
Here is the code that im using for level manager
public List<Button> levelButton;
public Sprite lockimage;
public bool delete;
private void Start()
{
int saveIndex = PlayerPrefs.GetInt("SaveIndex");
for (int i = 0; i < levelButton.Count; i++)
{
if (i <= saveIndex)
{
levelButton[i].interactable = true;
}
else
{
levelButton[i].interactable = false;
levelButton[i].GetComponent<Image>().sprite = lockimage;
}
}
}
public void LevelSelect()
{
int level = int.Parse(EventSystem.current.currentSelectedGameObject.name);
SceneManager.LoadScene(level);
}
public void PlayGame()
{
//code here
}
public void ResetGame()
{
PlayerPrefs.SetInt("SaveIndex", 0);
SceneManager.LoadScene(0);
}
public void DontResetGame()
{
SceneManager.LoadScene(0);
}
}
SceneManager.LoadScene(PlayerPrefs.GetInt("SaveIndex"));
edit: adding some info/context.
I realized that you set level buttons interactivity on the start functions based on the int save_index value you get from PlayerPrefs.
From there, I assumed that you could load the level directly using that same value on the PlayGame function.
Do note that the code I wrote will throw an error, if the "SaveIndex" key is not yet on PlayerPrefs
I put several button and i linked onClick() each buttons.
It's okay to print each button name.
But when i click another button, The text didn't combine previous text...
========================================================
public Text showText; //print text
public int count = 0; // count how many times click button
public void ButtonClick_1()
{
Debug.Log("Button Clicked!");
print(gameObject.name);
if (count == 0) { showText.text = gameObject.name; }
else { showText.text += gameObject.name; }
count++;
}
==================================================
First
click button1 => it's okay to print " button1 "
Second
click button1 again => It's okay to print " button1button1"
Third
click button2 => It's not okay to print. print like "button2". I hope it print"button1button1button2"
==========================================================
I want to figure out this.....
I have to put several buttons so use tag is more useful?
I'm not used to use tag. Hope someone help me out.
So as I understood you have this script on multiple buttons.
You have a check on count which initially is 0 for each individual instance.
So instead you could make it static so it is "shared" between all instances or better said makes it a static class member which is not related to any instance.
public Text showText;
public static int count = 0;
public void ButtonClick_1()
{
Debug.Log("Button Clicked!");
print(gameObject.name);
if (count == 0)
{
showText.text = gameObject.name;
}
else
{
showText.text += gameObject.name;
}
count++;
}
So that the text is only overwritten by the very first button click.
Your comment
Actually i print like "000" ,"001",,"012","123".
sounds like you actually want to print always the last three buttons.
I would rather use e.g. a static List<string> like
private static List<string> lastThreeButtons = new List<string>();
public void ButtonClick()
{
lastThreeButtons.Add(name);
if(lastThreeButtons.Count == 3)
{
showText.text = lastThreeButtons[0] + lastThreeButtons[1] + lastThreeButtons[3];
lastThreeButtons.Clear();
}
}
This is how I would do it :
Have a singleton class :
public class TextManager : MonoBehaviour
{
public static TextManager Instance;
public UnityEngine.UI.Text myUIText;
private void Awake()
{
Instance = this;
}
public void AddLine(string _line)
{
myUIText.text += $"{_line} \n";
}
}
Put this Component on a GameObject and link the UIText in the inspector
Then on my ButtonScript I would have this :
public void ButtonClick()
{
Debug.Log($"{gameObject.name} Clicked!");
TextManager.Instance.AddLine(gameObject.name);
}
I have created some buttons in Unity. When a button is clicked a function is called to write text on an InputText component. The function is following for example:
public void JButton()
{
textshowed.text = textshowed.text + "J";
}
But if I want to write a letter in between a line, the word is written at last of line.
What should i do for the letter to written where the cursor/caret is?
note that it doesnt handle selections in InputField. Below might be enough for your purpose?
public class button : MonoBehaviour
{
public InputField myInput;
int caretposition;
public void JButton()
{
myInput.text = myInput.text.Insert(caretposition, "J");
//Debug.Log(myInput.caretPosition);
}
private void Update()
{
if (myInput.isFocused)
{
caretposition = myInput.caretPosition;
}
}
}
I want focus input fields using tab button. I have found some code for focusing input fields but that one not satisfied my requirement. In my application one page design like number of input field in both horizontal and vertical formate. In my page have 3 rows of input field and each row have 3 input fields. my requirement is when user click on tab button focus next input field it's working but when reach end of the row, how can I focus next row contain input field. Please suggest any idea. Thank you. You can find my sample page design in below.
Here is the code I have tried.
Selectable next = system.currentSelectedGameObject.GetComponent<Selectable().FindSelectableOnRight();
if (next != null)
{
InputField inputfield = next.GetComponent<InputField>();
if (inputfield != null)
{
inputfield.OnPointerClick(new PointerEventData(system));
system.SetSelectedGameObject(next.gameObject, new BaseEventData(system));
}
}
I had implemented the a similar function by NGUI, you can make some modify if using UGUI. The idea is set the nextInput manually by public variable
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIInputTab : MonoBehaviour {
UIInput thisInput;
public GameObject nextInput;
void Start () {
thisInput = transform.GetComponent<UIInput>();
}
void Update () {
if (thisInput.isSelected)
{
if (nextInput != null && Input.GetKeyDown(KeyCode.Tab))
{
UICamera.selectedObject = nextInput;
}
}
}
}
Update
: Dynamic generate random number InputField and assign the next InputField.
InputfieldTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class InputfieldTest : MonoBehaviour {
public GameObject inputFieldPrefab;
public GameObject panel;
private GameObject lastInput;
EventSystem m_EventSystem;
void Start () {
m_EventSystem = EventSystem.current;
for(int i = 0; i < Random.Range(5,10);i++){
GameObject column = new GameObject();
column.transform.parent = panel.transform;
column.name = "Column" + i;
for (int j = 0; j < Random.Range(2, 8);j++){
GameObject input = Instantiate(inputFieldPrefab);
input.transform.parent = column.transform;
input.GetComponent<RectTransform>().position = new Vector3(300+ 200 * j, 300+ 200 * i, 0);
input.name = "InputField" + i + "-" + j;
// set nextInput
if(lastInput != null) {
lastInput.GetComponent<InputTabControl>().nextInput = input;
}
lastInput = input;
}
}
}
void Update () {
GameObject currentSelect = m_EventSystem.currentSelectedGameObject;
if (currentSelect != null)
{
print(currentSelect.name);
GameObject nextInput = currentSelect.GetComponent<InputTabControl>().nextInput;
if (nextInput != null && Input.GetKeyDown(KeyCode.Tab))
{
InputField inputfield = nextInput.GetComponent<InputField>();
if (inputfield != null)
{
inputfield.OnPointerClick(new PointerEventData(m_EventSystem));
m_EventSystem.SetSelectedGameObject(nextInput.gameObject, new BaseEventData(m_EventSystem));
}
}
}
}
}
InputTabControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputTabControl : MonoBehaviour {
public GameObject nextInput;
}
Result:
Here's my solution, pretty similar.
public class TabToNextController : MonoBehaviour {
public InputField nextField;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (GetComponent<InputField> ().isFocused && Input.GetKeyDown (KeyCode.Tab)) {
nextField.ActivateInputField ();
}
}
Just add this script to the item you want to be tabbed from. Then in the GUI drop in the inputfield you want to be tabbed to as the "nextField".
I recently ran into this problem and it drove me crazy to think there was no tabs feature. I had never noticed it before. A simple solution that seems to work so far is to use the Selectable class that the UI elements inherit from.
I tested this with the most common types (for me) - InputField, Buttons and drop down lists.
It tabs to each of them as expected
use spacebar to click the button
use spacebar to open the drop down
If you want full web style controls (eg arrow keys) to invoke the drop down, you need to write that code.
public class TabToNextController : MonoBehaviour, IUpdateSelectedHandler
{
public Selectable nextField;
public void OnUpdateSelected(BaseEventData data)
{
if (Input.GetKeyDown(KeyCode.Tab))
nextField.Select();
}
}
Cheers
This is what worked for me:
public Selectable next; //if you want the cursor to start at a specific field
//you can set this in the inspector to any input field
private EventSystem system;
private int tabIndex; //to keep track of cursor
void Start()
{
system = EventSystem.current;// EventSystemManager.currentSystem;
//if you don't want to set next in the inspector, you can do it here
//next = Selectable.allSelectables[0];
tabIndex = 0;
next.Select(); //make sure to do this!
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Tab))
{
if (tabIndex >= Selectable.allSelectables.Count)
{
next = Selectable.allSelectables[0];
tabIndex = 0;
}
else
{
//if nothing is selected then system.currentSelectedGameObject
//will throw a nullPointer Exception
next = system.currentSelectedGameObject.GetComponent<Selectable>()
.FindSelectableOnDown();
tabIndex++;
}
Debug.Log(next);
if (next != null)
{
InputField inputfield = next.GetComponent<InputField>();
if (inputfield != null)
inputfield.OnPointerClick(new PointerEventData(system)); //if it's an input field, also set the text caret
system.SetSelectedGameObject(next.gameObject, new BaseEventData(system));
}
}
}
The accelerometer is activated (if I set ReadingChanged it works).
Why the shaking event isn't handled?
namespace AppExample
{
public sealed partial class MainPage : Page
{
private Accelerometer accel;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
accel = Accelerometer.GetDefault();
//accel.ReadingChanged += accel_ReadingChanged;
accel.Shaken += accel_Shaken;
}
void accel_Shaken(Accelerometer sender, AccelerometerShakenEventArgs args)
{
Debug.WriteLine("shaken");
}
}
}
If you mind, there is helper librairy called ShakeGestures to handle shake gestures for windows phone 8. check this question
If you're running Windows Phone 8 , Shaken event won't trigger and does not raise any errors according to MSDN page.
Otherwise it seems like a weird bug to me , I couldn't find any information about it.
You can call the Dispatcher in order to show the result on the main thread.
namespace AppExample
{
public sealed partial class MainPage : Page
{
Accelerometer accel;
public MainPage()
{
this.InitializeComponent();
accel = Accelerometer.GetDefault();
accel.ReadingChanged += accel_ReadingChanged;
accel.Shaken += accel_Shaken;
}
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
LabelTest.Text = "Shaken!! " + args.Reading.AccelerationX.ToString();
});
async private void accel_Shaken(object sender, AccelerometerShakenEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
_shakeCount++;
ScenarioOutputText.Text = _shakeCount.ToString();
});
}
}
}