why i get error when i instance scene without add_child? how to fix it?

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

why i get error when i instance scene without add_child? how to fix it?

  • i want to add child but not on local scene, i want to add_child to main scene under canvas node.
  • example :
  • i have var invChest = preload (invChest path).instance() when i click chest, i want my chest node emit_signal( "open_chest", invChest ), then my ChestManager in main scene will pickup then will
    add child under canvas node in main scene.
  • reason why i did’t instance in main scene, because i want set some variable before instance, example if my chest have 3 slot, i want my invChest.slot = 3, and when my chest broken/queue_free, i want to get all item in inv chest, then spawn it in map.
  • everything work fine but when i exit game, will get this errorenter image description here

here to recreate this problem

  • first new control scene with with name instance_test2 and this code
 extends Control

var texture_res: TextureRect = TextureRect.new()
var slot = 6

func _ready() -> void:
	for q in slot :
		texture_res.texture = load("res://icon.png" )
		add_child( texture_res )

-create new node scene with this code

 extends Node2D

var ins_res = preload("res://instance_test2.tscn"  ).instance()
  • then you can play second scene and close it, and will get this error.

i also get the same error when i free all item
i click right click to free all i instance item
then close game

class_name MapClass extends Node2D

export ( NodePath ) onready var YSORT = get_node( YSORT ) as YSort


var item_res = preload("res://scene/Item/DropItem.tscn")
var all_test_drop_item : Array 


func _ready() -> void:
	for i in range(3):
		var new_drop = item_res.instance()
		var new_pos = get_node("YSort/Player").global_position + Vector2(rand_range(-300 , 300) ,rand_range(-300 , 300) )
		new_drop.global_position = new_pos
		new_drop.item_id = "ironSword"
		get_node("YSort").add_child(new_drop)
		all_test_drop_item.append( new_drop )
	
	$Label.text = str(get_tree().get_nodes_in_group("drop_item").size())


func _input(event: InputEvent) -> void:
	if Input.is_action_just_pressed("L_Click"):
		for i in all_test_drop_item:
			i.queue_free()
:bust_in_silhouette: Reply From: omggomb

In the first script you create a TextureRect node. Since you instance that scene in the second script but don’t add it to the scene tree, you need to manually free both, the TextureRect and the instanced scene itself:

extends Control

var texture_res: TextureRect = TextureRect.new()
var slot = 6

func _ready() -> void:
    for q in slot :
        texture_res.texture = load("res://icon.png" )
        add_child( texture_res )

func cleanup():
    texture_res.queue_free()

then…

extends Node2D

var ins_res = preload("res://instance_test2.tscn"  ).instance()

func _ready():
    ins_res.cleanup()
    ins_res.queue_free()