Unable to get Input using Custom Keyboards in an Unity App , both iOS and Android.
private var keyboard : TouchScreenKeyboard;
var text : String = "";
function Start() {
keyboard = TouchScreenKeyboard.Open(text, TouchScreenKeyboardType.Default);
}
function Update() {
if (keyboard != null && keyboard.done)
{
text = keyboard.text;
print ("User input is: " + text);
}
}
Did you try this?
Related
As the title suggests, my button (closeImage) goes null when I try to access it.
I have a canvas that pops up an image based on a tapped marker (button component) on a map. The said canvas will show the image together with the button in question. Clicking on the button closes the pop-up;
The button in question
However, once I press on the marker on the map to show the pop-up image, it gives me an error that the Close image is null. The close button does show on the first time I press on the marker on the map and able to close the pop-up, even with the error message. But once I click on the same marker on the map again, the image shows but the close button is not showing anymore.
Here's my block of code:
public class TappedMarkerManager : MonoBehaviour {
private static TappedMarkerManager instance;
private List<GameObject> markerImageList = new List<GameObject>();
string tappedMarkerName;
Button closeImage;
GameObject closeImageGO;
public static TappedMarkerManager Instance {
get {
if (instance == null) {
instance = FindObjectOfType<TappedMarkerManager>();
}
return instance;
}
}
void Start() {
closeImageGO = GameObject.FindGameObjectWithTag("close_img");
if(closeImageGO != null) {
closeImage = closeImageGO.GetComponent<Button>();
closeImage.onClick.AddListener(TappedMarkerInformation);
} else {
Debug.Log("closeImageGO is null");
}
//Loop through preview images.
//This will dynamically add the images on the list if more markers will be added on the map
//Use tag "marker_img"; must be same name with the marker and image
var markerImages = GameObject.FindGameObjectsWithTag("marker_img");
foreach(var markerImage in markerImages) {
TappedMarkerManager.Instance.markerImageList.Add(markerImage.gameObject);
//Set false to hide it at first
markerImage.SetActive(false);
}
}
public void TappedMarkerInformation() {
var name = tappedMarkerName;
foreach(var img in TappedMarkerManager.Instance.markerImageList) {
if(name == img.GetComponent<Image>().name) {
img.SetActive(true);
if(closeImage != null) {
if(!closeImage.gameObject.activeInHierarchy) {
closeImage.gameObject.SetActive(true);
}
} else {
Debug.LogError("Close image is null");
}
}
if(GetButtonName() == "ExitBtn") {
img.SetActive(false);
closeImage.gameObject.SetActive(false);
}
}
}
public void SetTappedName(string name) {
tappedMarkerName = name;
TappedMarkerInformation();
}
//Get the name of the button pressed
public string GetButtonName() {
if(EventSystem.current.currentSelectedGameObject != null) {
string ClickedButtonName = EventSystem.current.currentSelectedGameObject.name;
return ClickedButtonName;
} else {
return "";
}
}
}
The markers on the map are controlled from another script with:
...
TappedMarkerManager tappedMarkerManager;
tappedMarkerManager = new TappedMarkerManager();
...
private void HandleFingerTap(LeanFinger finger) {
Ray ray = Camera.main.ScreenPointToRay(finger.ScreenPosition);
if (Physics.Raycast(ray, out RaycastHit hit)) {
string markerName = hit.collider.gameObject.name;
tappedMarkerManager.SetTappedName(markerName);
}
}
Any help is highly appreciated. Thank you. I can provide the github repository if needed.
What I tried so far:
I already tried setting up the closeImage in the Inspector with the button
Made sure that the GameObject has the button component
Checked and verified on the hierarchy that the closeImage button is not being destroyed
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.
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));
}
}
}
I have downloaded the Watson unity SDK and set it up like show in the picture and it works.
My question is how do I add keyword spotting?
I have read this question For Watson's Speech-To-Text Unity SDK, how can you specify keywords?
But I cant for example locate the SendStart function.
The Speech to Text service does not find keywords. To find keywords you would need to take the final text output and send it to the Alchemy Language service. Natural Language Understanding service is still being abstracted into the Watson Unity SDK but will eventually replace Alchemy Language.
private AlchemyAPI m_AlchemyAPI = new AlchemyAPI();
private void FindKeywords(string speechToTextFinalResponse)
{
if (!m_AlchemyAPI.ExtractKeywords(OnExtractKeywords, speechToTextFinalResponse))
Log.Debug("ExampleAlchemyLanguage", "Failed to get keywords.");
}
void OnExtractKeywords(KeywordData keywordData, string data)
{
Log.Debug("ExampleAlchemyLanguage", "GetKeywordsResult: {0}", JsonUtility.ToJson(resp));
}
EDIT 1
Natural Language Understanding has been abstracted in tot he Watson Unity SDK.
NaturalLanguageUnderstanding m_NaturalLanguageUnderstanding = new NaturalLanguageUnderstanding();
private static fsSerializer sm_Serializer = new fsSerializer();
private void FindKeywords(string speechToTextFinalResponse)
{
Parameters parameters = new Parameters()
{
text = speechToTextFinalResponse,
return_analyzed_text = true,
language = "en",
features = new Features()
{
entities = new EntitiesOptions()
{
limit = 50,
sentiment = true,
emotion = true,
},
keywords = new KeywordsOptions()
{
limit = 50,
sentiment = true,
emotion = true
}
}
if (!m_NaturalLanguageUnderstanding.Analyze(OnAnalyze, parameters))
Log.Debug("ExampleNaturalLanguageUnderstanding", "Failed to analyze.");
}
private void OnAnalyze(AnalysisResults resp, string customData)
{
fsData data = null;
sm_Serializer.TrySerialize(resp, out data).AssertSuccess();
Log.Debug("ExampleNaturalLanguageUnderstanding", "AnalysisResults: {0}", data.ToString());
}
EDIT 2
Sorry, I didn't realize Speech To Text had the ability to do keyword spotting. Thanks to Nathan for pointing that out to me! I added this functionality into a future release of Speech to Text in the Unity SDK. It will look like this for the Watson Unity SDK 1.0.0:
void Start()
{
// Create credential and instantiate service
Credentials credentials = new Credentials(_username, _password, _url);
_speechToText = new SpeechToText(credentials);
// Add keywords
List<string> keywords = new List<string>();
keywords.Add("speech");
_speechToText.KeywordsThreshold = 0.5f;
_speechToText.Keywords = keywords.ToArray();
_speechToText.Recognize(_audioClip, HandleOnRecognize);
}
private void HandleOnRecognize(SpeechRecognitionEvent result)
{
if (result != null && result.results.Length > 0)
{
foreach (var res in result.results)
{
foreach (var alt in res.alternatives)
{
string text = alt.transcript;
Log.Debug("ExampleSpeechToText", string.Format("{0} ({1}, {2:0.00})\n", text, res.final ? "Final" : "Interim", alt.confidence));
if (res.final)
_recognizeTested = true;
}
if (res.keywords_result != null && res.keywords_result.keyword != null)
{
foreach (var keyword in res.keywords_result.keyword)
{
Log.Debug("ExampleSpeechToText", "keyword: {0}, confidence: {1}, start time: {2}, end time: {3}", keyword.normalized_text, keyword.confidence, keyword.start_time, keyword.end_time);
}
}
}
}
}
Currently you can find the refactor branch here. This release is a breaking change and has all of the higher level (widgets, config, etc) functionality removed.
I've little trouble with my simple game.
I'm using this code for menu control:
#pragma strict
var isIZADJI=false;
function OnMouseEnter()
{
renderer.material.color=Color.red;
}
function OnMouseExit()
{
renderer.material.color=Color.white;
}
function OnMouseUp()
{
if(isIZADJI)
{
Application.Quit();
}
else
{
Kontrola_Zivota.ZIVOTI=3;
Application.LoadLevel(1);
}
}
When I click "Play Again" it works fine but when I click "Exit" it just load first level.
Any help here?
I just thought I'd expand on the solution:
I was reading through your code and I see that what you were looking for was a way to identify which button was clicked. I would like to expand on your answer for anyone who want's to know what your solution was. The way to solve this is to create a string variable to check the name of the thing you are clicking (assuming this is GUI Button) and then to change the state of the var isIZADJI based on that eg:
// izlaz[croatian] = exit[english]
// First create a string var for the name of button/GUI/object
var nameOfButton : String;
function OnMouseUp()
{
if(!(nameOfButton == "izlaz"))
{
isIZADJI = false;
}
else
{
isIZDAJI = true;
}
// And then now you can add the rest of your code to quit or load a level
if(isIZADJI)
{
Application.Quit();
}
else
{
Kontrola_Zivota.ZIVOTI=3;
Application.LoadLevel(1);
}
}
I hope this helps anyone else with this problem.