"If" Condition Matches but Doesn't Run Code

Godot Version

4.4 Stable

Question

Hey, everyone!

I’m attempting to make a dialogue system that displays whole strings, however, my function seems to run the code in the “else” statement even before matching the conditions for that to happen, stopping the timer and as such cutting off the string. Strangely, it works fine in the first line, but any subsequent lines face this issue.

Other issues:

" visible_characters " skips straight to the third letter when it should load only the first letter
The timer also seems to go faster with each line that is loaded? That might be just me though!

Please ask me if I was unclear about anything, I’ll try to provide information as best as I can! I apologize in advance if my topic’s name was not clear.

Here is the code that performs logic on the strings (Though I can also provide other code if needed!)

extends Node2D
@onready var portrait := $CanvasLayer/Container/Portrait
@onready var portcont := $CanvasLayer/Container
@onready var dialogue := $CanvasLayer/Text
@onready var timer = $Timer
@onready var audioplayer := $TalkSoundPlayer
var maxLineSize := 64
var currentLine := 0
@export var textSpeed := 0.5
@export var dialogueArray : Array[Dialogue]
func _physics_process(delta: float) -> void:
    if Input.is_action_just_pressed("interact"):
        currentLine += 1
        _load(dialogueArray[currentLine].text, dialogueArray[currentLine].portrait)
func updateArray(newData) -> void:
    if typeof(newData) != typeof(dialogueArray):
        push_error("Not an array of dialogue! Please check the variable that is being parsed:" + newData)
    else:
        dialogueArray = newData
        _load(dialogueArray[0].text, dialogueArray[0].portrait)
func _load(text : String, pic : CompressedTexture2D) -> void:
    dialogue.visible_characters = 0
    if (pic == null):
        #idk how this will work in lower screen resolutions so Uh
        dialogue.position.x -= dialogue.position.x / 3
    else:
        portrait.texture = pic
        portrait.set_hframes(2)
    if (text.length() > maxLineSize):
        push_error("Dialogue too big! Shorten this line! " + text)
        return
    
    print(text.length())
    
    displayText(text)
func displayText(text : String):
    
    print(text.length())
    dialogue.text = text
    
    #reset for new dialogue
    timer.set_wait_time(0.05)
    dialogue.visible_characters = 0
    
    timer.start()
    timer.timeout.connect(
        func():
            audioplayer.play()
            
            #flip between 0 and 1
            if dialogue.visible_characters % 2 == 0:
                portrait.frame = 1 - portrait.frame
            
            if dialogue.visible_characters < text.length():
                match text[dialogue.visible_characters]:
                    "!", ",", ".", ":", ";", "?":
                        timer.set_wait_time(0.15)
                    _:
                        timer.set_wait_time(0.05)
                dialogue.visible_characters += 1
            else:
                portrait.frame = 0
                timer.stop()
            print(dialogue.visible_characters)
    )

(Apologies for not attaching the video directly, I have a new account and can’t attach it!)

Video


You are connecting the function multiple times, once every time the displayText function is run.

Try to only connect timeout on ready or through the editor.

1 Like