How do I check if a node is visible?

Godot Version

4.6.1

Question

I’m making a drag-and-drop hotbar using this tutorial. When an item is selected on the hotbar, it shows a panel, and when you click it again, it hides it. But when I click another item in the hotbar while something is already selected, it shows the panel over the other panel. I would like to hide the other panel when another item is selected. How can I achieve this?

Thanks in advance. I feel I need to say that I’m not asking anyone to make the whole system for me.

You can use is_visible_in_tree() if a parent has been hidden, or self.visible for the node itself.

1 Like

So I figured out how to do it; it probably isn’t the best way, but it’s fine for now.

I decided to create a global variable to hold the path for the visible node, but then I got an error, so I changed it to a panel (but you can change it to whatever node you’re using; in my case, it’s a panel). I also created two new scripts with the visibility_changed() function:

func _visibility_changed():
	if self.visible == true:
		autoload._node = self
	else:
		pass

Autoloaded script:

extends Node

var _node: Panel

And in the item_slot.gd, I created a new if statement where I check if the autoloaded variable isn’t null, and then I set the variable to be equal to the panel that’s showing. Then I hide it and show the item in the hotbar that was clicked:

#Checking if the global variable isn't null
			if autoload._node != null:
				#Getting the global variable
				var _node = autoload._node
				#Setting it's visibility to false
				_node.visible = false
				#Setting the other node's visibility to true
				node.visible = true
				#Printing the global variable for debugging
				print(str(autoload._node))

If you know a way to improve this, please tell me :slight_smile:

If anyone wants access to the full project, I included it in the original post.

You had a much simpler and bug prone solution in the first reply.

.is_visible_in_tree() checks all the parents and the node itself. If all are visible, it returns true.

You may prefer to use a static variable instead, it’s like a global but for the script/class. Maybe you can also assign it when visible, rather than using a separate script and relying on signals elsewhere

static var active_panel: Panel = null

# aside: you can use `get_node_or_null` to avoid errors logged
var node = get_parent().get_parent().get_parent().get_node_or_null(item.path)
if event.is_action_pressed("l_click") and node != null:
	if active_panel:
		active_panel.visible = false
	node.visible = true
	active_panel = node
1 Like

Doesn’t work

Any error messages? The static var may need to be declared outside of the function.

Yep, I needed to put the static var outside the function. Thank you.

Ok, just now realized this, but I can’t unselect it.

Maybe you could check if the active panel is the same selected one?

if active_panel == node:
    node.visible = false
    active_panel = null
1 Like

Thank you very much for all of your help!