Display text character by character

Hi all!

I use Cocos Creator version 3.8.3.

Look at the following example:

00

There are two objects here. One is just a sprite. The second one has a Label component. The first object has the following properties:

01

The second object has the following properties:

I need to force the text to be output at, for example, 20 characters per second.

The simplest thing I can do (without going into details about speed) is to just add characters (without the nuances of surrogate pairs):

this.label.string += character;

Unfortunately this will have two problems for me:

First, entering added text will shift already added text. It was like this:

03

Then it became like this:

04

Adding a space and ‘T’ character moved the rest of the text. I don’t need this kind of behavior.

Secondly, unfinished words try to squeeze into the free space. If they succeed, there will be a subsequent shift when the completed word does not fit into the same space. Look at the example:

05

I don’t like that the letter ‘t’ took up space on the same line. After adding the next letter, everything will fall into place:

06

But the displacement effect itself has already worked.

How can I eliminate these two effects that are undesirable for me?

I decided to try a trick with the RichText component. Here are the settings of the object with this component:

Adding a character is done as follows:

let leftText = text.substring(0, index);
let rightText = text.substring(index);
this.richText.string = `${leftText}<color=#00000000>${rightText}</color>`;

It’s gotten better, but there are still a number of problems:

  1. Some text shaking may occur.
  2. There is no “Overflow Processing” property to be able to select “SHRINK”.
  3. The “color” tag breaks into words.

Let’s enter the following text into RichText:

Hello! This is an example <color=#00000000>text.

Result:

08

Let’s add character ‘t’ to the visible ones:

Hello! This is an example t<color=#00000000>ext.

Result:

09

As you can see, the “color” tag splits the word into two words. Is this a bug? As far as I remember, a similar trick worked in Unity.

In general, how can I solve this problem?

And in general, does the engine have any functions for working with text? For example, how can I find out the text size without entering it into a visual component and then reading the values ​​when everything is applied?

According to your two questions:
1.What kind of behavior do you want for first question.
2.Please try this context for two question: Hello! This is an example t<color=#000000>ext.</color>

Note: Here is the link to show you how to use tags in RichText:RichText Component Reference | Cocos Creator

Regarding the first question. I expected that when outputting text via the RichText component, the already output text would not shift when I mask the unoutput text via transparency. However, in reality, sometimes the already output text dances.

Regarding the “color” tag. I showed a bad example. In reality, the text is displayed as you showed. This is what my code demonstrates:

let leftText = text.substring(0, index);
let rightText = text.substring(index);
this.richText.string = `${leftText}<color=#00000000>${rightText}</color>`;

As you can see, there is a closing tag “color” at the end of the text. And, as I said, the “color” tag itself breaks the word into subwords. I think this is a mistaken behavior. After all, if I need to break a word into subwords, I will add a space. At least that’s how it worked in Unity.

Anyway, how can I implement the behavior I need?

  1. The text does not shake due to the addition of new characters.
  2. A part of an unfinished word should not be placed where the whole word would not fit.

And additionally: is there any functionality for working with the dough (find out the size and all that…)?

1.You can set the node UITransform component anchor to (0, 0.5), then set RichText component horizontal Align to Left. then it will show the result like the video below:

2.There are too many 0 in color value. You can use <br/> tag to break a word into subwords.

3.Could you describe more details of your additional question " is there any functionality for working with the dough (find out the size and all that…)"

If I do this, I will get something like this:


And I need it to be like this:

In general, so that the text on the new line is centered. This is the final result. And when the text is displayed character by character, the characters need to be inserted in the places shown in the picture above.

I don’t need to break words. If I break words, then some characters from the word will be stuffed where they shouldn’t be. And I don’t understand how I can’t output some characters from the word so that the output characters are part of the word so that they aren’t located where I don’t need them.

I’ll show an example from Unity. There, a similar component is called TextMeshPro - Text (UI). As text I entered:

Hello! This is an example t<color=#FF000000>ext.

Here is the result:

But if I entered it like this:

Hello! This is an example t

Then the result would be like this:

That’s why I pointed out the difference in operation between the RichText components from Cocos Creator and TextMeshPro - Text (UI) from Unity. And I like the behavior of the latter more, it allows me to solve my problem. And how can I solve my problem in Cocos Creator?

Well, for example, in Unity there is a Font class, which has a GetCharacterInfo() function.

I discovered another strange thing.

When I run the example in the browser on the computer (in the editor I press Play), the text is displayed character by character, but with the same problems that I wrote about earlier.

But when I build for Web-mobile and run the example on the phone, then my text is displayed not by characters, but by words. This is very strange!

You probably can compare with this solution here and get a few ideas how to fix your code

That’s not it. What ideas can there be, I already output correctly. This RichText has “strange” behavior. And it works slowly on the phone.

RichText is infamous for its performance, both on Unity and Cocos.

Cocos does not provide TextMesh out of the box. You can find some solutions to buy in the store if you don’t know how to implement them yourself