Getting the child im clicking on from parent

Godot 4.5

Im sure this is a very basic thing but i cant seem to figure it out.
I have a VBoxContainer as my inventory, and items which are control nodes are added as children. Currently the Inventory doesnt keep any kind of track of whats in it, though it could.
All i want is to be able to click on the children to take them out. I know I could probably add a gui event to the items themselves, but that seems like a lot of useless code when theres a lot of them, and i’d rather just have the parent VBoxController detect when its clicked on, and which item i clicked over. I guess the way youd do this is compare mouse coords with its own, and since items all have the same height you could calculate which one down it is? Though the VBoxController is in a ScrollContainer, and i dont know if those coords are gonna work once you start scrolling? Also, once i know that the one being clicked on is the third one down, i still dont know how to tell which of the vboxes children that is.

Thanks in advance

1 Like

You’re definitely overcomplicating it.

Why not just use a Button for your items? Signal pressed will be emitted when you click on it. Then you can connect() a function to that signal and do whatever you want to do with it.

No position/height calculation is needed.

2 Likes

above reply is what i did. and before the day i myself invented it a inventory. not much but i guide you,

don’t read this if have an idea how to make it or have better youtube video,

this is not most useful way to create inv, i had created it and store number of object whose value and names are random.

create an array in global script like Main (make it and apply it is not present as default that’s the magic)

Main.gd

var inv : Array = [];
var max_inv : int = 5;
var default_img := preload("you're choice")

func new_dict_inv() -> Dictionary:
     return {
       "name" = "Useles",
        "value" = 100,
        "img" = Texture2D,
        };

func _ready():
     for i in range(max_inv):
          max_inv.append(new_dict_inv());

not you have created a inventory not vissible but it is in the code,

first create a button node which carries a script and save it where you want, i’ll name it as ”slot.tscn”

var name : String = "";
var value : String = "";
var img : Texture2D;

func _process(_delta : float) -> void:
     if name == "":
        icon = Main.default_img;
     else:
        icon = img;

in you’re VBoxController you have to create button child with some images that’s easy. this below is new script of VBoxController

var slot := preload("res://slot.tscn"); #loading the slot
func _create() -> void:
     for i in Main.inv:
         var btn : Button = slot.instantiate();
         add_child(btn);
         btn.name = i["name"];
         btn.value = i["value"];
         btn.img = i["img"];
         btn.custom_minimum_size = Vector(100, 100); #you're fav size

#for updating it
func _update() -> void:
     for i in range(Main.inv.size()):
         get_child(i).name = Main.inv[i]["name"];
1 Like

yup, that was a better solution. thanks :smiley:

1 Like