How do I stop a dialogue window from opening up right after it's closed?

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

So, I copied the code from the JRPG demo in the Godot example projects. But I didn’t want the button on the dialogue window, so I removed it and had the player advance dialogue by pressing the “ui_accept” button. But this is the same button that the player uses to trigger the dialogue window in the first place! So when they reach the end of the dialogue by pressing the “ui_accept” button, it just opens the dialogue window again!

How do I stop this from happening?

Which demo are you talking about? Can you provide a link? Or even better: the relevant portion of your code?

njamster | 2020-03-06 16:14

This is the demo I’m talking about.

The relevant part of my code is (from the player’s KinematicBody2D node):

func _physics_process(delta):
if Input.is_action_just_pressed("ui_accept"):
	for body in $Area2D.get_overlapping_areas():
		if body.has_method("show_dialogue"):
			body.show_dialogue()
			return

exuin | 2020-03-06 23:42

:bust_in_silhouette: Reply From: njamster

Just looked through the demo code. show_dialogue does this:

dialogue_node.connect("dialogue_started", player, "set_active", [false])
dialogue_node.connect("dialogue_finished", player, "set_active", [true])

And set_active is defined as:

func set_active(value):
	active = value
	set_process(value)
	set_process_input(value)

So starting the dialogue disables the processing of inputs for the player and finishing it enables it again. In order to fix your problem, you have to refine set_active:

var can_talk = true

func set_active(value):
	active = value
	set_process(value)
	set_process_input(value)

    if value == false:
        can_talk = false
    else:
        yield(get_tree().create_timer(1.0), "timeout")
        can_talk = true

This way, can_talk will switch to false immediately when starting the dialogue, but it will take a second until it resets to true after you finished the dialogue.

Now all that’s left to do is changing your script slightly:

func _physics_process(delta):
    if can_talk and Input.is_action_just_pressed("ui_accept"):
        for body in $Area2D.get_overlapping_areas():
            if body.has_method("show_dialogue"):
                body.show_dialogue()
                return

That’s of course just one way to fix your problem, but it should give you an idea.

Thanks for the solution, it worked.

exuin | 2020-03-08 04:36