0 votes

This code is supposed to hide/show my UI when I collect something, what's wrong with it? The UI gets cut short often when collecting stuff.

var timer = Timer.new()

func _on_GeluLumenLapis_body_entered(body: Node) -> void:
    hide()
    $CollisionShape2D.set_deferred("disabled", true)
    get_parent().get_parent().get_node("Node2D/LapisCounter/UI").show()
    timer()

func timer():
    timer.connect("timeout",self,"do_this")
    timer.wait_time = 3
    timer.one_shot = true
    add_child(timer)
    timer.start()

func do_this():
    get_parent().get_parent().get_node("Node2D/LapisCounter/UI").hide()
    queue_free()
Godot version v3.5.stable.official [991bb6ac7]w
in Engine by (34 points)

Are you collecting two things in short succession? I could see the UI getting cut short in that case.

1 Answer

+2 votes
Best answer

As exuin commented, the problem is likely caused by player collecting 2 items in succession - the first one shows the counter and counts to 3. You collect the second item, and it tries to show the counter (which is already visible) and counts to 3. But before the second timer has reached zero, the first timer finishes and hides the counter.

Solution: Instead of the item handling ui show/hide, have a script in the counter itself, which is responsible of showing/hiding itself. Something like this:

var timer = Timer.new()

func _ready() -> void:
    add_child(timer)
    timer.wait_time = 3
    timer.connect("timeout", $UI, "hide") # Connect signal to UI node's hide function

func _on_GeluLumenLapis_body_entered(_body: Node) -> void:
    $UI.show()
    timer.start()

Now have the item simply call item_collected()from the item - or even better, simply connect body_entered to that function. Which you can do from some parent object so that the items don't need to actually know where the ui node is located - this kind of decisions will save a ton of headache later on if you happen to rename some of the ui nodes.

EDIT: updated the code according to comments below

by (1,100 points)
selected by

Thanks! I'll try this soon and probably report back to you.

If this is supposed to go in the counter's script:

extends Node


var timer = Timer.new()

func _ready() -> void:
    timer.wait_time = 3
    timer.connect("timeout", self, "hide")

func _on_GeluLumenLapis_body_entered(_body: Node) -> void:
    get_parent().get_parent().get_node("Node2D/LapisCounter/UI").show()
    timer.start()

Then why doesn't it hide the UI after the timer ends?
(body_entered is correctly connected.)

Ah, my bad. Forgot that Timer won't work if it hasn't been added to the scene tree. Simply add this in the _ready():

add_child(timer)

Also if this code is in counter's script, you can just call show(), no need to go through parents and back again to get reference to self :)

OK thank you!!!

I get "Parser Error: The method "show" isn't declared in the current class."

Why is this happening?

Oh. Your counter node is a Node, so it doesn't have show and hide functions. Judging by code the UI is it's child. In that case here's the (hopefully) final version:

func _ready() -> void:
    add_child(timer)
    timer.wait_time = 3
    timer.connect("timeout", $UI, "hide") # Connect signal to UI node's hide function

func _on_GeluLumenLapis_body_entered(_body: Node) -> void:
    $UI.show()
    timer.start()

THANK YOU!!!

No problem :)
If you found my answer helpful, you should set it as an accepted answer. It might help somebody with similiar problem in future...

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.