Options to do typewriter effect work

Godot Version

4.1.2

Question

Hi all.
I am encountering some issues when trying to work with some typewriter effect on some text.
The effect works great in a scene where I only have the text Label within a TextRect; as I play the scene, the text starts with the effect until its completion.

What I need to do now is: when the character collides with a certain item, the text scene appears.

I am trying by adding the text scene to the main scene, not visible. When the character collides, the text scene gets visible. The process works, but the typewriter effect does not start from the beginning of the text, but in the middle or afterwards.

I already tried lots of options and scripts -even with RichTextLabel effects- but could not figure it out.

Any suggestion you could give me to fix this?

I attach two videos to make it clear.
Single scene working: https://streamable.com/93cywx
Scene within the main scene, not working: https://streamable.com/ot81rb

And this is the code for the script for the typewriter effect:

extends TextureRect

var total_characters = 0
var text_speed = 2

func _ready():
	# count numbers of characters in text
	total_characters = $Label.text.length()
	# initially no text displayed
	$Label.visible_characters = 0
	
func _process(delta):
	if $Label.visible_characters < total_characters:
		$Label.visible_characters += text_speed

Thanks a lot :slight_smile:

Two options:

  1. Instantiate the text scene through code when the character collides with the relevant item
  2. Change your script so there’s a function you can call in order to start the typewriter effect. That could look something like:
extends TextureRect

var total_characters = 0
var text_speed = 2
var is_typing = false

func _ready():
	# count numbers of characters in text
	total_characters = $Label.text.length()
	# initially no text displayed
	$Label.visible_characters = 0
	
func _process(delta):
	if is_typing:
		if $Label.visible_characters < total_characters:
			$Label.visible_characters += text_speed

func start_typing():
	is_typing = true
1 Like

Thank you.
For some reason, it is not working :frowning:

The script is fine, but as i set var is_typing = false at the start of the code, the text does not run (of course the text runs if set var is_typing = true, but same issue than before.

Instantiating neither works.
I’ll continue searching the reason.

I mean, the idea is that you then call the start_typing function when you want the effect to start - have you tried that?

1 Like

You need to call start_typing when the scene becomes visible.

Also, you should adjust the speed based on the delta variable if you don’t want the speed of the effect to depend on the speed of the computer on which the game is running.

1 Like

Yes, I tried.
I think my problem is with some order regarding layers and visibility.

I will try to go through the process, to make myself clearer.

When the character collides with the item ‘wood’, the script attached to item ‘wood’ makes it disappear and makes visible the node ‘n1-wood’ that contains the elements - one of them the text with the effect:

The item ‘wood’ script is:

extends Area2D

# This function is called when a body enters the area

func _on_body_entered(body):
	if (body.name == "CharacterBody2D"):
		# Queue the area to be removed from the scene tree
		queue_free()
		$"../n1-wood".visible = true

And this is the script attached to the ‘Label’ subode, which should launch the typewritten text:

extends Label

var total_characters = 0
var text_speed = 2
var is_typing = false

func _ready():
	# count numbers of characters in text
	total_characters = $".".text.length()
	# initially no text displayed
	$".".visible_characters = 0
	
func _process(delta):
	if is_typing:
		if $".".visible_characters < total_characters:
			$".".visible_characters += text_speed

func start_typing():
	is_typing = true

The node tree looks like this:

Hope it is more clear.
Thanks guys!

Alright, I continued trying to make it work, and with your hints and some help from chatgpt, it is working.
I connected a ‘_on_visibility_changed’ function that resets visible_characters and accumulated_time variables, and starts typing when the node becomes visible.

I attached this script to Label, just in case you guys find it useful:

extends Label

var total_characters = 0
var text_speed = 70
var is_typing = false
var accumulated_time = 0.0

func _ready():
	# count numbers of characters in text
	total_characters = text.length()
	# initially no text displayed
	visible_characters = 0
	# connect the visibility_changed signal to the _on_visibility_changed function
	connect("visibility_changed", Callable(self, "_on_visibility_changed"))

func _process(delta):
	if is_typing:
		if visible_characters < total_characters:
			accumulated_time += delta * text_speed
			while accumulated_time >= 1.0:
				visible_characters += 1
				accumulated_time -= 1.0
				if visible_characters >= total_characters:
					break

func start_typing():
	is_typing = true

func _on_visibility_changed():
	if visible:
		visible_characters = 0
		accumulated_time = 0.0
		is_typing = true
	else:
		is_typing = false

Thank you so much for your help :slight_smile:

1 Like