How to detect clicks on a dynamically updated TextMeshProUI text? - c#

I'm trying to implement a functionality that can determine which word in the text the user clicked on. To do this, I use the TextMeshProUGUI element and the following code:
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro;
public class ExtraWordsDefinition : MonoBehaviour {
public TextMeshProUGUI text;
public string LastClickedWord;
void Start()
{
text = GetComponent<TextMeshProUGUI>();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
var wordIndex = TMP_TextUtilities.FindIntersectingWord(text, Input.mousePosition, null);
if (wordIndex != -1)
{
LastClickedWord = text.textInfo.wordInfo[wordIndex].GetWord();
Debug.Log("Clicked on " + LastClickedWord);
}
}
}
}`
This code works fine if the text in the element is static (i.e.the text that I specified in the component's settings in the Unity inspector) then the words I click on are displayed in the console.
But, if I try to change the text of the component dynamically through the code, then the script stops detecting clicks on the text at all (the if condition does not work). Also, this way of changing text resets the text alignment settings.
At first I made code where the text was changed by assigning a new string to the ".text" property, but I also tried changing the text through the SetText() method, but that didn't change anything. Unfortunately, searching the internet didn't help me find an answer either.
Please help me figure out what is the reason.

First, I would add logs to verify that the mouse Vector and the TextMesh Vector are compatible. If that is the case, I would add a print when the test is updated and when the mouse is pressed to verify that the mouse pressing happens after the text has been updated and that the positions are still correct. I would also print the index to see if the text is actually found at the given position or if there is another problem. Also, ensure that nothing has a higher layer order than the text mesh after you change the text.

Related

Transferring text of an input field to another input field on Unity

Im working on this Unity AR project and im trying to add a function where I can transfer text of an input field to another input field.
I have tried various scripts and have tried it on the app but the text of input field still cannot be transferred to another input field.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RemarksTransfer : MonoBehaviour
{
public string theRemarks;
public GameObject inputField;
public GameObject textDisplay;
public GameObject secondInput;
public void StoreRemarks()
{
theRemarks = inputField.GetComponent<Text>().text;
textDisplay.GetComponent<Text>().text = theRemarks;
if (textDisplay.TryGetComponent<InputField>(out var secondInput))
{
secondInput.text = theRemarks;
}
}
}
This is the code that I have used. However, this is for transferring text from an input field to a text box instead of another input field. Therefore, displaying the text only but not being able to edit on it.
Long story short, Im just trying to transfer text from an input field to another input field and the text can be edited if the user wants to edit.
What you’re seeing here is a GameObject that has an InputField. For an InputField to work correctly, it has an associated Text component. Your code is looking for the Text component. Now, if your second object DOES have an InputField component, search for that, and use its text property to get and set the text. You should also bring doing the same thing for your original InputField as well. As the Unity documentation says, the visible text shown might be truncated, or have asterisks if it’s a password. That’s what you’d get, instead of the actual underlying text value.
So, assuming your textDisplay has an InputField component, you could use:
if ( textDisplay.TryGetComponent<InputField>( out var secondInput ) )
{
secondInput.text = theRemarks;
}

How to select an object by script - Unity

I am a beginner in Unity and I am currently making a simple game. I have a problem where I need to select an object automatically by script so I can click outside of it without clicking on it in the screen.
What I want to do is when I click the object another object or panel will show and it will be automatically be selected by script so I can click outside the panel and it will close or will setActive to false. I tried the Select() and it is not working for me. The two objects are originally an Image but I added a Button component so it can be selectable.
This is the script for the object that will show the Panel:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ShowPhone : MonoBehaviour, ISelectHandler
{
[SerializeField] Button phonePanel;
public void OnSelect(BaseEventData eventData)
{
phonePanel.gameObject.SetActive(true);
}
}
This is the script for the panel where I want to click outside to close it:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class HidePhoen : MonoBehaviour, IDeselectHandler
{
public Button phone;
private void OnEnable()
{
phone.Select();
}
public void OnDeselect(BaseEventData data)
{
Debug.Log("The Object will be setActive false when clicked outside the object");
}
}
You would use EventSystem.SetSelectedGameObject
EventSystem.current.SetSelectedGameObject(yourTargetGameObject);
Note though: Your panel would automatically be closed even if clicking any UI element within it (like e.g. InputField etc)
You can checkout the TMP_Dropdown source code and the way they implemented a "UI Blocker" which basically is an overlay over the entire screen except the drop-down popup and closes the pop-up when clicked on.
you could either replicate this or have a simpler version with a fully transparent background button behind your panel with onClick for closing the panel.
As alternative you could check RectTransformUtility.RectangleContainsScreenPoint

how can i edit text in the UI within a script?

I wanted to edit the text in the UI to display a health value and score. but I don't know how I would go about creating code to edit the piece of text in the first place
To edit the Text component in Unity you need to do this:
Create a public Text field. In a function, for example Start (), it assigns a string to the Text component. Go to the inspector to assign the Text component to the public field.
using UnityEngine;
using UnityEngine.UI;
public class ChangeText : MonoBehaviour
{
public Text text;
void Start()
{
text.text = “example text”;
}
}
See the documentation here.
if you think my answer helped you, you can mark it as accepted. I would very much appreciate it :)

Button not highlighting

I create a set of prefabs at runtime via script. They are held in an array called newObj. Each one has some text UIs and some buttons, which I retrieve with GetComponentsInChildren. When a user clicks the first button in the prefab, I want to run a function that changes the text of the button and highlights that button.
Everything is working except the button doesn't highlight.
public void SelectPlayer(int rowSelected)
{
var buttons = newObj[rowSelected].GetComponentsInChildren<Button>();
var texts = newObj[rowSelected].GetComponentsInChildren<Text>();
texts[0].text = "1";
buttons[0].Select();
buttons[0].OnDeselect(null);
}
Oops. I'm still new to Unity and forgot that Unity sets the default highlight color to white (for some reason). Once I changed it for my prefab using the editor, all was well.

Problem with rich text and how it updates on the screen in unity

For my game, I wish to have a dialogue system where some words in the dialogue are colored differently. Right now, I have my normal white text being typed to the screen using the .ToCharArray command. This allows me to type one letter at a time to my screen. I've also looked and found something called Rich Text and Markup, which allows me to color my text with different colors while leaving the rest white. The issue is, the sentence is being typed and then updated in the ui to show the color, so for a brief second, are shown until the text changes green. Is there any way to make it so the text is typed with the color in effect? is there an asset that lets me change colors of certain words in unity? Any help would be appreciated!
Inside the DataBlock Scriptable object, ive typed the sentance i want into the text area. I then put and around the word I wanted to change. This caused the TypeSentance Coroutine to type out the sentance pulled from the scriptable object. This also made it so the TypeSentance Coroutine to print out the and around the text before updating a second later.
First Script
public class DataBlock : ScriptableObject
{
[Tooltip("Please Put Body Text In Here")]
[SerializeField] [TextArea(3, 10)] string bodyText;
public string getBodyText()
{
return bodyText;
}
}
Second Script
public class GameCode : MonoBehaviour
{
[SerializeField] DataBlock[] DataBlocks;
int currentDataBlock = 0;
private void update()
{
updateGraphic()
}
public void updateGraphic()
{
StopAllCoroutines();
StartCoroutine(TypeSentance(DataBlocks
[currentDataBlock].getBodyText()));
currentDataBlock++
}
IEnumerator TypeSentance(string sentance)
{
bodyTextBox.text = "";
foreach (char letter in sentance.ToCharArray())
{
bodyTextBox.text += letter;
yield return new WaitForSeconds(0.001f);
}
}
}
I expected the result to be that the text is outputted in the color of my choice, but instead it was printed with the and and then updated to show the color
Your description is not clear as you are missing some characters and don't give your example bodyText. Also it is not clear wich UI component you use.
Nevertheless I assume you are setting invalid tags as text as you iterate through your string. You find more about supported RichtText in Unity's documentation.
Example:
This text works fine:
"This text is <color=green>green</color> and <color=red>red</color>"
This text is missing a closing </color>-tag and wont be parsed as RichText by the UI.Text component:
"This text is <color=green>gree
To resolve this, you can parse the text (every time you extract a part) and check if you are missing a closing tag. If a tag is missing, you just add it at the end.
Also you have to ignore start-tags.
There are more things wrong with your code
Update must be written uppercase. Otherwise it is not called by Unity. But i guess are you calling it yourself from somewhere else? Than it is very misleading and should be renamed.
private void Update()
{
updateGraphic()
}
If you are updating correctly but a frame is showing the text full white, you only need to update the text while the object is off (gameObject.SetActive(false)) and then turn it off to apply the change on the very first frame gameObject.SetActive(true).

Categories

Resources