- Home /
Display fixed number of words in textbox at a time
Hi I have been trying to figure this out with no luck.
I am receiving text from an API and sometimes the text is received with over 10 words and sometimes only one word. I would like to write a script that will only allow up to 3 words to be displayed at a time in a text box on screen.
Then after 2 seconds it will move to the next three words. If there is less than three words it will only display the remaining words. Once it is finished I would like to call the API again to get more text. Can anyone help with this please?
I have been trying to create a lot of if statements but I am not sure how I would get the logic right? I think I might be overcomplicating this. Please help if there is an easier way. Thank you!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using JacobGames.SuperInvoke;
public class TesxtMeshAi : MonoBehaviour
{
int count = 0;
public Text Ai;
public string AiMesh;
string CombText;
private string[] TextBreak;
public int timer;
public GameObject Call; // the api to call
public TextMeshProUGUI textDisplay;
void Start()
{
AiMesh = Ai.text;
textDisplay.text = AiMesh;
TextChange();
}
public void TextChange()
{
AiMesh = Ai.text;
TextBreak = AiMesh.Split(char.Parse("_"));
// textDisplay.text = AiMesh;
count = 0;
SuperInvoke.RunRepeat(3, 1, TextBreak.Length, RunText);
void RunText()
{
if (count + 2 > TextBreak.Length)
{
CombText = TextBreak[count] + " " + TextBreak[count + 1];
count = 0;
Call.GetComponent<TestChatEasy>().Call();
}
if (count + 1 > TextBreak.Length)
{
Call.GetComponent<TestChatEasy>().Call();
}
if (count > TextBreak.Length) //was old one
{
count = 0;
Call.GetComponent<TestChatEasy>().Call();
}
if (count >= 0)
{
if (TextBreak.Length < 2)
{
CombText = TextBreak[count] + " " + TextBreak[count + 1];
textDisplay.text = CombText;
count = 0;
Call.GetComponent<TestChatEasy>().Call();
// TextChange();
}
if (TextBreak.Length < 1)
{
CombText = TextBreak[count];
textDisplay.text = CombText;
count = 0;
Call.GetComponent<TestChatEasy>().Call();
// TextChange();
}
if (TextBreak.Length > 3)
{
count = count + 1;
CombText = TextBreak[count] + " " + TextBreak[count + 1] + " " + TextBreak[count + 2];
textDisplay.text = CombText;
}
}
}
Answer by Firnox · Feb 02 at 02:09 PM
I am assuming your Call.GetComponent<TestChatEasy>().Call();
updates Ai.text
and calls the TextChange()
function. In which case I'd do this using a coroutine.
public void TextChange() {
StartCoroutine(RunText(Ai.text));
}
IEnumerator RunText(string words) {
string[] word = words.Split('_');
string output;
int idx = 0;
while (idx < word.Length) {
// The condition above ensures that the first word is available.
output = word[idx++];
for (int i = 0; i < 2; i++) {
// Break out if we run out of words, else add them on.
if (idx >= word.Length) { break; }
output += " " + word[idx++];
}
// Set the text.
textDisplay.text = output;
// Wait for 2 seconds
yield return new WaitForSeconds(2);
}
// When we reach here we've finished with the words get some more.
Call.GetComponent<TestChatEasy>().Call();
}
Hi Thank you for your answer. I just tried it an unfortunately I am getting an out of range error. I adjusted the code to add in the inco$$anonymous$$g text but it should not have effected the coroutine?
Here is the error: IndexOutOfRangeException: Index was outside the bounds of the array. DisplayTXTNew+d__10.MoveNext () (at Assets/Scripts/DisplayTXTNew.cs:41) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)
Please let me know if there is any advice how to fix this. Thank you. Here is the new code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class DisplayTXTNew : MonoBehaviour
{
public Text Ai;
public string AiMesh;
string[] word;
public GameObject Call;
// TextMeshPro textmeshPro;
public TextMeshProUGUI textDisplay;
// Start is called before the first frame update
void Start()
{
TextChange();
}
public void TextChange()
{
AiMesh = Ai.text;
// word = AiMesh;
StartCoroutine(RunText(Ai.text));
}
IEnumerator RunText(string words)
{
word = AiMesh.Split(char.Parse(" "));
string output;
int idx = 0;
while (idx < words.Length)
{
// The condition above ensures that the first word is available.
output = word[idx++];
for (int i = 0; i < 2; i++)
{
// Break out if we run out of words, else add them on.
if (idx >= words.Length) { break; }
output += " " + words[idx++];
}
// Set the text.
textDisplay.text = output;
// Wait for 2 seconds
yield return new WaitForSeconds(2);
}
// When we reach here we've finished with the words get some more.
Call.GetComponent<TestChatEasy>().Call();
}
}
Sorry there was a bug in my original code, I didn't actually run it to test it sorry. I have modified that now. The issue is that the comparisons are on words.Length in the while and if statement. They should be on "word.Length" (I also should have chosen better names for the variables!). So what this is doing is comparing it to the length of the string, not the number of words. Simlarly words[idx++] should have been word[idx++]
Thank you so much for all of your help!!!! This is working so well! I will read up more about coroutines for the next project. Cheers!
Your answer
Follow this Question
Related Questions
What's your equivalent of old GUIStyle ? 0 Answers
Planning Text Scroll with Unity UI 0 Answers
How to know the font height in pixels (and other attributes) of a text? 1 Answer
Which type of Variable do I need to use to change the Value of a text UI object ? 0 Answers
Display user Input to a text UI element. 0 Answers