This code is supposed to hide/show my UI when I collect something, what's wrong with it?

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

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()

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

exuin | 2022-12-08 21:40

:bust_in_silhouette: Reply From: aXu_AP

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

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

DJSlimeball | 2022-12-10 07:07

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.)

DJSlimeball | 2022-12-10 07:49

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 :slight_smile:

aXu_AP | 2022-12-10 20:50

OK thank you!!!

DJSlimeball | 2022-12-10 22:30

I get “Parser Error: The method “show” isn’t declared in the current class.”

Why is this happening?

DJSlimeball | 2022-12-11 01:44

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()

aXu_AP | 2022-12-11 07:41

THANK YOU!!!

DJSlimeball | 2022-12-11 10:11

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

aXu_AP | 2022-12-11 13:46