What happens is that I'm instancing a node as a child of another one through code using add_child. This is part of my inventory system, as the instanced node appears when getting an item. In order to instance the node I'm using the following function:

func ObjectToInventory(slot, item_name, texture_to_load):
	slot.add_child(InventoryItemInstance)
	slot.get_node("Item1").name = item_name
	slot.get_node(item_name).ItemTexture = load(texture_to_load)
	slot.get_node(item_name).texture_normal = load(texture_to_load)

ObjectToInventory(item_slots, "LEDTubeLight", "res://Textures/UI/InventoryImages/LEDTubeLight.png")
(InventoryItemInstance is the node I want to instance, which was defined before:

var InventoryItemScene = preload("res://Scenes/Assets/UI/InventoryItem.tscn")
var InventoryItemInstance = InventoryItemScene.instance()

This part of the code works perfectly, the problem is that the node is a button, and it doesn't seem to work when instancing it through code. The issue is not from the node itself, as I tried adding it through the editor, and it worked.

I also checked the remote tab, and the node was instanced correctly.
Before getting the item:

After getting the item:

I used is_instance_valid() to check if the node was instanced correctly, by printing something if it's valid. When I add the node from the editor, the instance is valid, but when it's added through code, it doesn't seem to be, as nothing is printed.

Any help would be appreciated

  • ThinKing_2005 replied to this.
  • Darxkl05

    Darxkl05 onready var LEDTubeLight = ItemSlots.get_node_or_null("LEDTubeLight")

    This is a problem... what if "on ready", the node "LEDTubeLight" is not present yet, but is added later? Instead, use this in the FIRST LINE INSIDE "physics process (delta)":
    var LEDTubeLight = ItemSlots.get_node_or_null("LEDTubeLight")

    EDIT
    This right here explains what's happening actually. When the node is added via the editor, the node is present "on ready" (meaning from the very beginning). But when added through code, it's not there "on ready", but later on. From the remote tree, I'm pretty sure the instance is valid. So it's probably a much simpler problem, e.g. node is invisible.

    You probably want this:

    var InventoryItemScene = preload("res://Scenes/Assets/UI/InventoryItem.tscn")
    # remove this line: var InventoryItemInstance = InventoryItemScene.instance()
    ...
    slot.add_child(InventoryItemScene.instance())

      cybereality I've tried that, but it doesn't work, it's still doing the same thing. A new node appears as a child of the other one, but the instance is still not valid, so it doesn't work. Is there any other way to fix the issue?

      Can you post the code where you are checking the instance?

      Here it is

      onready var LEDTubeLight = ItemSlots.get_node_or_null("LEDTubeLight")

      #Inside physics process (delta)
      if is_instance_valid(LEDTubeLight): #To check if the node is instanced
      		print("Node Instanced")
      	
      if is_instance_valid(LEDTubeLight) and LEDTubeLight.is_pressed(): #Do the following if the instance is valid and button is pressed
      		ItemSelected("LEDTubeLight", "A LED tube light found on the rail tracks, it must have fallen from the walls")
      		Use.disabled = false
      		Combine.disabled = false
      		Examine.disabled = false

        Darxkl05

        Darxkl05 I used is_instance_valid() to check if the node was instanced correctly, by printing something if it's valid. When I add the node from the editor, the instance is valid, but when it's added through code, it doesn't seem to be, as nothing is printed.

        From what I know, an instance is invalid when the instance is freed (e.g. queue_free() is used). Here is a quote from https://docs.godotengine.org/en/stable/classes/class_@gdscript.html#class-gdscript-method-is-instance-valid:
        #QUOTE START
        "bool is_instance_valid ( Object instance )
        Returns whether instance is a valid object (e.g. has not been deleted from memory)."
        #QUOTE END

        This means that, if your check for is_instance_valid() is used correctly, the node must be "non-existent." Try checking using this print(is_instance_valid()).

        I also noticed that you never explained how exactly did you get the idea that the node is

        Darxkl05 doesn't seem to work when instancing it through code

        Did you not see the node being there in the inventory?

        Overall, there is definitely more code that needs to be shown. If your check for is_instance_valid() is working, then the node must be "freed" somewhere in the code. But maybe it's a much simpler problem, for example the node is set to be invisible or something. But, from what's shown, it definitely is strange.

          Darxkl05

          Darxkl05 onready var LEDTubeLight = ItemSlots.get_node_or_null("LEDTubeLight")

          This is a problem... what if "on ready", the node "LEDTubeLight" is not present yet, but is added later? Instead, use this in the FIRST LINE INSIDE "physics process (delta)":
          var LEDTubeLight = ItemSlots.get_node_or_null("LEDTubeLight")

          EDIT
          This right here explains what's happening actually. When the node is added via the editor, the node is present "on ready" (meaning from the very beginning). But when added through code, it's not there "on ready", but later on. From the remote tree, I'm pretty sure the instance is valid. So it's probably a much simpler problem, e.g. node is invisible.

            ThinKing_2005 From what I know, an instance is invalid when the instance is freed (e.g. queue_free() is used).

            As your last post indicates, you kinda already figured it out, but might as well post this anyways to confirm: another situation where an instance can be invalid is when it hasn't been created, added to the scene and initialized yet.

            It might help to do this either after you add the node with script or before you try to check it:

            LEDTubeLight = ItemSlots.get_node("LEDTubeLight")

            ThinKing_2005 Thank you so much, I just had to put the variable inside physics process (delta). I didn't know something like this would work, mostly because my knowledge when it comes to instances and freed nodes is kind of limited