I’m having a bit of trouble with the dialogue system in my game. Every time a user interacts with an object, several lines of dialogue are played. I introduced a timer that automatically progresses the dialogue after 1 second. However, when the user interacts with another object before the lines finish playing, the rest of the first interaction still plays.
Example: object 1 has two lines of dialogue (“Hello!; How are you?”"), and object 2 has one (“Howdy!”). The user interacts with object 1 first, then quickly with object 2, interrupting the lines of the first object.
How it should be (with interruption):
- object 1: “Hello!”
- object 2: “Howdy!”
How it is instead:
- object 1: “Hello!”
- object 2: “Howdy!”
- object 1: “How are you?”
The question is, how do I cut off the second line from playing?
Relevant code:
func type_reaction(outfit : ChoiceButton):
if outfit.lines != []:
for i in outfit.lines:
print(i.line)
next_line_timer.start()
await next_line_timer.timeout
Hi,
I believe that the code to change is not inside the code you’ve shared: that code displays the lines and seems to be working fine.
What seems to be missing is a lines clear when interacting with an object. Something that would look like this:
func on_object_interacted():
outfit.lines.clear()
outfit.lines.append_array(object_lines)
This is just pseudo code as I don’t know much about your project’s code, but hopefully you get the idea.
Let me know if that helps, and please share more of your code if you need a more precise help!
2 Likes
Hello! Thank you for your response, but I don’t think this is the issue.
I guess I should have clarified, but the outfit.lines array is an array of custom resources (contains a sprite and a string) tied to each individual outfit. It remains unchanging, so I don’t think I need to clear it.
The dialogue displaying code is also not the issue, because in my code above I’m printing to the console, and it still doesn’t work like I need it to.
I think the problem is that the timer for the next line starts when the first line of object1 is finished, and when the timer goes off, the second line is printed, regardless of if a new line is playing at the moment or not. But I have no idea how to fix it.
I see, indeed the solution is not as straightforward as I thought it would be.
Could you share more of the code?
I don’t really know what other code to share, but here:
This is in the same dialogue-controlling node I showed earlier:
func _ready():
dresses.new_outfit_picked.connect(type_reaction)
func type_reaction(outfit : ChoiceButton):
if outfit.alphys_line != []:
for i in outfit.alphys_line:
print(i.line)
next_line_timer.start()
await next_line_timer.timeout
This is in the dresses node:
signal new_outfit_picked
func set_outfit_number(name : String, outfit_number : int, new_outfit: ChoiceButton):
picked_outfit[name] = outfit_number
new_outfit_picked.emit(new_outfit)
This is in the node that holds all outfits:
func ready_up(): ## called when opened
for child in get_children():
outfits.append(child)
if not child.is_connected("outfit_chosen", on_outfit_chosen):
child.outfit_chosen.connect(on_outfit_chosen)
func on_outfit_chosen(chosen_outfit : ChoiceButton):
var chosen_outfit_number = outfits.find(chosen_outfit)
dresses.set_outfit_number(self.name, chosen_outfit_number, chosen_outfit)
And in the ChoiceButton:
signal outfit_chosen(ChoiceButton)
func _on_pressed():
if !button_chosen:
button_chosen = true
outfit_chosen.emit(self)
Everything else works fine beside the dialogue issue.
Thank you.
In that code:
func _ready():
dresses.new_outfit_picked.connect(type_reaction)
func type_reaction(outfit : ChoiceButton):
if outfit.alphys_line != []:
for i in outfit.alphys_line:
print(i.line)
next_line_timer.start()
await next_line_timer.timeout
It seems that whenever you pick an oufit, you call type_reaction
, which will loop through its lines, without considering any dialogue that could be running already. In that case, that would explain why two dialogues are overlapping, as they’re just playing side by side without knowing about each other.
Would something like this work?
var dialogue_running: false
func _ready():
dresses.new_outfit_picked.connect(type_reaction)
func type_reaction(outfit : ChoiceButton):
if dialogue_running:
print('A dialogue is running already')
return
dialogue_running = true
if outfit.alphys_line != []:
for i in outfit.alphys_line:
print(i.line)
next_line_timer.start()
await next_line_timer.timeout
dialogue_running = false
Not saying that using a dialogue_running
boolean is the perfect solution, but if my code prevents your issue from happening, that would prove my guess is right. And then you can find the proper solution!
1 Like
Thank you! That worked, now all dialogue finishes running. I kind of wanted the new dialogue to interrupt the already running one, but maybe your solution is better.
1 Like
That works too, it all depends on your design choices. Code-wise, both solutions can be done easily.
Anyway, glad I could help!