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 
Two options:
- Instantiate the text scene through code when the character collides with the relevant item
- 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 
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 
1 Like