- Home /
Typewriter with coloured text
I'm wondering whether it's possible to harness the rich text format options in conjunction with the AutoType script on the wiki (http://wiki.unity3d.com/index.php?title=AutoType).
The main problem I've found is as it splits the string into characters and types them out one-by-one, it would take the html tags for colouring with it and type those out, meaning you wouldn't get the colour until that section of the string is finished.
Here's the script, by the way:
var letterPause = 0.2;
var sound : AudioClip;
private var word;
function Start () {
word = guiText.text;
guiText.text = "";
TypeText ();
}
function TypeText () {
for (var letter in word.ToCharArray()) {
guiText.text += letter;
if (sound)
audio.PlayOneShot (sound);
yield WaitForSeconds (letterPause);
}
}
Answer by robertbu · Mar 23, 2014 at 10:43 PM
There's no easy way to do it using rich text as input. You could scan for the color tags yourself and then output a color tag for each character. Or you can do it using a parallel data structure and output color tags for each character. Here is a simple example of a parallel data structure. Attach the following script to a GUIText object. Note that the string output is now in the script rather than taken from the GUI text:
var letterPause = 0.2;
var sound : AudioClip;
public var text : String = "Here is some text";
public var colors : Color[] = [Color.red, Color.white, Color.yellow, Color.black,
Color.blue, Color.cyan, Color.gray, Color.green,
Color.magenta, Color.red, Color.red, Color.red,
Color.green, Color.green, Color.green, Color.red,
Color.red];
function Start () {
TypeText ();
}
function TypeText () {
var charArray = text.ToCharArray();
for (var i = 0; i < charArray.Length; i++) {
if (i <= colors.Length - 1) {
guiText.text += "<color="+ColorToHexString(colors[i])+">"+charArray[i]+"</color>";
Debug.Log(guiText.text);
}
else {
guiText.text += charArray[i];
}
if (sound)
audio.PlayOneShot (sound);
yield WaitForSeconds (letterPause);
}
}
function ColorToHexString(color : Color) : String {
var color32 : Color32 = color;
return String.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", color32.r, color32.g, color32.b, color32.a);
}
In order to keep it simple, I've established a color array that matches each character to a color. You can modify this to something that is more efficient. You could parse out the `` tags and do the same thing I've done here and output a separate color/end color tag set for each character.
Hey, sorry to dig this up again, but I heard a way to do it was by positioning multiple GUI Labels next to each other. I'm wondering if you or anybody else would know how to do this in the way I've got with the original script and keeping wordwrap of some sort? I figured you could use .calcSize() to work out how long each word was for word wrapping but it's a case of getting that to work with each label printed next to each other.
Though I've worked an alternate solution nearly a year on, I'm marking this as answered. Thanks for the help.
Answer by GabLeRoux · Mar 03, 2019 at 01:12 AM
Here's a similar script as above, but in CSharp. Didn't do what I was looking for exactly, but it works.
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class ColoredTypewriterText : MonoBehaviour
{
[SerializeField]
float letterPause = 0.2f;
[SerializeField]
Text label;
public string text = "0123456789";
public Color[] colors = {
Color.red,
Color.white,
Color.yellow,
Color.black,
Color.blue,
Color.cyan,
Color.gray,
Color.green,
Color.magenta,
Color.green
};
void Start()
{
StartCoroutine(TypeText());
}
IEnumerator TypeText()
{
var charArray = text.ToCharArray();
for (var i = 0; i < charArray.Length; i++)
{
if (i <= colors.Length - 1)
{
label.text += "<color=" + ColorToHexString(colors[i]) + ">" + charArray[i] + "</color>";
}
else
{
label.text += charArray[i];
}
yield return new WaitForSeconds(letterPause);
}
}
string ColorToHexString(Color color)
{
Color32 color32 = color;
return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", color32.r, color32.g, color32.b, color32.a);
}
}
I did not record a gif, but it types each character at a rate of letterPause
Answer by FunFreighterGames · Sep 25, 2020 at 08:56 PM
I know this is old, but I ran into the same problem and found that it was a lot easier to use text mesh pro add whatever string you need into text mesh pro text and increment maxVisibleCharacters. That way you can ignore any rich formatting tags and just let text mesh pro handle it.
myTMPText.text = myString;
for (lettersDisplayed = 0; lettersDisplayed < dialogueLength; lettersDisplayed++)
{
myTMPText.maxVisibleCharacters = lettersDisplayed;
yield return new WaitForSeconds(letterDelay);
}
Hi. I have been looking for it for a while. Can you please share the entire code to see how you implemented it? Thanks!