I am trying to build a simple text animation, like a type-writer, where characters appear one after the other.

I managed to build something with RichTextEffect:

extends RichTextEffect
class_name RichTextAppear

var bbcode = "appear"

func _process_custom_fx(char_fx):
	var speed = char_fx.env.get("speed", 1)
	
	var elapsed_time = char_fx.elapsed_time * speed
	var step = 1.0/speed
	var index = char_fx.absolute_index
	
	if elapsed_time < index:
		char_fx.color.a = 0
	elif elapsed_time > index and elapsed_time < index + step:
		var animation_delta = elapsed_time - index
		char_fx.color.a = animation_delta
	else:
		char_fx.color.a = 1

	return true

Is there a better way to create the text effect? What is causing the massive performance hit? I don't see anything in the code.

I am sure that the RichTextEffect is causing the problem. A test scene with just the RichTextLabel with this effect is already eating half the CPU time on my machine. (which is a bit older)

Label has a percent_visible property that can be animated.

Limits the count of visible characters. If you set percent_visible to 50, only up to half of the text’s characters will display on screen. Useful to animate the text in a dialog box

It looks like you are changing the alpha on a per-character basis, which sounds intensive to me. Usually you want to limit the amount of transparent objects that you use in a scene, and doing an alpha animation on potentially hundreds of objects is probably too much.

Most games that rely on text (like visual novels) don't use transparency, they just draw each character in sequence, which appears to be what "percent_visible" does, as @mr_moon recommends.

Thank you @mr_moon and @cybereality for your fantastic comments.

I think the best way is to animate visible_characters property, since the characters will be animated at a constant speed, no matter how many characters the text has.

However, even this method gives me performance issues. The problem is in my scene setup, I can make it run smoothly again by hiding the sprites I use for the dialogues. I find it strange that I only have around 10 sprites visible and it still tanks my performance.

I am developing on an older machine, an early 2013 MacBook, which is great for finding performance bottlenecks early. But I would not expect this to be a problem even on an old machine.

I would love to find the root cause for this. Maybe I should open a new thread. ?

@cybereality said: It looks like you are changing the alpha on a per-character basis, which sounds intensive to me. Usually you want to limit the amount of transparent objects that you use in a scene, and doing an alpha animation on potentially hundreds of objects is probably too much.

Most games that rely on text (like visual novels) don't use transparency, they just draw each character in sequence, which appears to be what "percent_visible" does, as @mr_moon recommends.

I would not think that the transparency should be a preformance issue, since only one character at a time will have be transparent. But you are right that it is not needed, since the character will appear so quickly that the animation is not noticable. So the transparency is not needed.

Ah I see. Yeah, if it's only one character at a time it should be within reason, but best not to waste performance where it is not needed or noticeable.

In terms of performance, that is strange. I get that you're using a pretty old machine, but text rendering should be cheap (or I would hope so). Maybe I will take a look tomorrow, I have some old laptops I can test with.

In the mean time, can you share a minimal project that shows the issue? Either that or just explain how to recreate the project and/or how it's supposed to work. I'll see what I can do.

If the animation speed varies, you can write a simple function that counts the string length and adjusts the animation speed accordingly.

@mr_moon said: If the animation speed varies, you can write a simple function that counts the string length and adjusts the animation speed accordingly.

You are right, this is better, since then I know when the animation is done! ?

@cybereality said: In terms of performance, that is strange. I get that you're using a pretty old machine, but text rendering should be cheap (or I would hope so). Maybe I will take a look tomorrow, I have some old laptops I can test with.

In the mean time, can you share a minimal project that shows the issue? Either that or just explain how to recreate the project and/or how it's supposed to work. I'll see what I can do.

Thank you for offering your help! I sent you a stripped-down version of the project. :)

3 years later