In my game, I have an interaction system which calls the function LabelInteraction() every time the player interacts with something. Visually, this shows a label that progressively appears thanks to a tween and then, after a SceneTreeTimer times out, the label disappears. The issue I’m encountering is that if the function is called when the timer from a previous call hasn’t finished, the new text disappears (HideLabel is called) before, as it’s using the timer from before. How can I fix this and use a new timer for every interaction, basically ignoring what the previous function’s timer value was?
Here’s the code
extends CanvasLayer
var timer
# Called when the node enters the scene tree for the first time.
func _ready():
$Label.visible_ratio = 0
LabelInteraction("This is a test ight but just a bit longer just in case")
func ShowLabel(label):
var tween := create_tween()
$Label.text = label
tween.tween_property($Label, "visible_ratio", 1.0, 0.5).from(0.0) #So it always plays the tween from the start
func HideLabel():
var tween := create_tween()
tween.tween_property($Label, "visible_ratio", 0.0, 0.5)
func LabelInteraction(label):
#Calculate time depending on string size
var words = label.split(" ") #Splits all the words in the string
var time = 2.5 * (words.size()*0.2) #Default time
if timer != null:
timer.time_left = 0
timer = get_tree().create_timer(time)
#Label
ShowLabel(label)
await timer.timeout #Waits for the timer to emit the timeout signal before executing hide label
HideLabel()
i see you are using timer to hide label after some time based on the words
so rather than do use timer, you can just use tween interval then tween property again to hide the label in ShowLabel
func ShowLabel(label,time_delay):
var tween := create_tween()
$Label.text = label
tween.tween_property($Label, "visible_ratio", 1.0, 0.5).from(0.0) #So it always plays the tween from the start
tween.tween_interval(time_delay)
tween.tween_property($Label, "visible_ratio", 0.0, 0.5)
func LabelInteraction(label):
#Calculate time depending on string size
var words = label.split(" ") #Splits all the words in the string
var time = 2.5 * (words.size()*0.2) #Default time
#Label
ShowLabel(label,time)
or if you insist to keep using the HideLabel function
func ShowLabel(label,time_delay):
var tween := create_tween()
$Label.text = label
tween.tween_property($Label, "visible_ratio", 1.0, 0.5).from(0.0) #So it always plays the tween from the start
tween.tween_interval(time_delay)
tween.tween_callback(HideLabel)
func LabelInteraction(label):
#Calculate time depending on string size
var words = label.split(" ") #Splits all the words in the string
var time = 2.5 * (words.size()*0.2) #Default time
#Label
ShowLabel(label,time)
While your interpretation is correct, neither of the approaches you mentioned worked. To illustrate it better, here’s a video of the issue
As the video shows, the second label disappears way quicker than it should be, as it’s using the timer from the first interaction (both labels for each of the interactions last around 7 seconds). And then, when interacting again, the new label still disappears early because it’s using the timer it had from the previous interaction. What’s wrong with the code that’s causing the game to use the previous timer?
what’s the expected interaction will happen to the label?
if you interact it first, it will show to full, but when you interact it second time while it’s full, what will happen?
so instead of creating new tween every time ShowLabel is called, use a universal tween so you can reset(kill) it for each new ShowLabel
var tween:Tween
func ShowLabel(label,time_delay):
if tween:
tween.kill()
tween=create_tween().bind_node(self)
$Label.text = label
tween.tween_property($Label, "visible_ratio", 1.0, 0.5).from(0.0) #So it always plays the tween from the start
tween.tween_interval(time_delay)
tween.tween_property($Label, "visible_ratio", 0.0, 0.5)
func LabelInteraction(label):
#Calculate time depending on string size
var words = label.split(" ") #Splits all the words in the string
var time = 2.5 * (words.size()*0.2) #Default time
#Label
ShowLabel(label,time)
To clarify the overall idea, the main problem was that the labels (which have a specific time assigned to them based on the words), were on-screen for a shorter or longer time depending on whether the function was already executing or not, and the expected result was that, independently of the function calls, each interaction and the label that comes with it had to be on-screen for a specific period of time