Cannot add pauses to dialogue display based on character when using bbcode.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Rickers

I am trying to write a way of displaying text which is able to pause (briefly) when certain characters are detected (e.g. pause for a second when you reach a full stop).

However, for some reason I cannot get the pauses to match up with the characters when it gets round to actually displaying text.

It seems that the get_total_character_count() is different from the actual length of the string given (with added bbcode), and somewhere in this mix the visible character’s variable is thrown off.

What this means is that when i add a string like “[center] This is a line of text, I think! And this is another poorly punctuated line, right?[/center]” instead of getting the pauses at the commas or question/exclamation marks it is at some offset.

If you see in the code below, it shouldn’t be so difficult, I pass a variable which i think will return the current character being displayed, and if that character is a piece of punctuation, pause the char_timer and wait until the pause_timer gives its timeout() signal.

However, for some reason it wont work consistently when bbcode is added like in the above example.

I have tried (and partially found) some solutions.

If I try to just use a regular text label with the following code, all the offsets are still off, despite there being no bbcode even added to the string. (this is something to do with get_total_characters in Label not including whitespace for some reason).

I can also use the dialogue[count].length()-8 or -9 to provide the offset needed to get the proper pauses, but this isn’t a great option as it won’t let me use bbcode as i’d fully like and i’d have to add the [center][/center] tags to every line of text which just seems kind of hacky and not a good practice to rely on when i’m having a non-coder provide some dialogue in future.

Here is the code now:

(forgive the shoddy code if its off by 1 in some way as I have tried to reconstruct here without all the spaghetti debugging stuff and its been through many alternations and iterations),

extends RichTextLabel
var dialogue
var count = 0
onready var char_timer = $char_timer
onready var pause_timer = $pause_timer
func _ready():
	bbcode_text = dialogue[count]
	visible_characters = 0 
func _process(_delta):
	rect_scale.x = abs(rect_scale.x)
func _on_char_timer_timeout():
	if visible_characters < get_total_character_count():
		var curr_character
		if get_visible_characters() >=get_total_character_count():
			curr_character = ""
		else:
			curr_character = dialogue[count][get_visible_characters()+8]
		visible_characters += 1
		pause(curr_character)
	else:
		count += 1
		if count < dialogue.size():
			visible_characters = 0
			bbcode_text = dialogue[count]
		else:
			char_timer.stop()
func pause(character):
	if character == ".":
		char_timer.stop()
		print("At this bit: "+character)
		pause_timer.wait_time = 0.8
		pause_timer.start()
		yield(pause_timer,"timeout")
		char_timer.start()
	elif character == "!" or character == "?":
		char_timer.stop()
		print("At this bit: "+character)
		pause_timer.wait_time = 1.2
		pause_timer.start()
		yield(pause_timer,"timeout")
		char_timer.start()
	elif character == ",":
		char_timer.stop()
		print("At this bit: "+character)
		pause_timer.wait_time = 0.4
		pause_timer.start()
		yield(pause_timer,"timeout")
		char_timer.start()

Have I found some weird bug or am I just missing something? Thanks.

:bust_in_silhouette: Reply From: exuin

If I have the text [b]text[/b] the total character count is 4, since the bbcode tags aren’t included in the character count. Therefore, you should use the text property of the RichTextLabel, which is the bbocde text just without the bbcode tags.

Thanks for the response, and I can certainly work with some of this, but how can I get it to work with the bbcode? The problem i’m having is the combining of bbcode with any string I use, which is resulting in pauses happening in the wrong places.

Rickers | 2021-02-24 21:16

You can still use BBCode. Just, instead of getting the current character from your dialogue array, you can use the .text property in the RichTextLabel to get the character without BBCode.

exuin | 2021-02-24 21:18

Ah perfect, I can finally say its working perfectly, massive thanks for your patience and quick reply.

For future people reading this, the code for curr_character = dialogue[count][comment2-get_visible_characters]was essentially changed to: curr_character = text[visible_characters] and I replaced the lines with dialogue[count].length with get_total_character_count() and I replaced bbcode_text with just text in the _ready() function

Rickers | 2021-02-24 23:26