Topic was automatically imported from the old Question2Answer platform.
Asked By
genete
Old Version
Published before Godot 3 was released.
I have one node that should be freed upon a button click and immediately I need that a new fresh instance of that node would be inserted on the scene again:
func _on_Button_pressed():
get_node("Piezas").queue_free()
var piezas=load("res://piezas/escenas/piezas.tscn")
var piezas_inst=piezas.instance()
piezas_inst.set_name("Piezas")
add_child(piezas_inst, true)
pass
But it always insert “Piezas 2” instead of “Piezas” as node name. This makes me think that “Piezas” node is still at tree.
How should I proceed to eliminate a node and immediately (as soon as possible) insert a new instance of it in the scene with exactly the same name?
You can design your code so you know the node is deleted, or not have it depend on its name. It can be done by keeping the node in a variable and setting this variable to null once you queue free the node, so its name doesn’t matter because you just need to check the variable without using get_node.
func _on_Button_pressed():
call_deferred("insertar_piezas")
pass
func insertar_piezas():
get_node("Piezas").free()
var piezas=load("res://piezas/scenas/piezas.tscn")
var piezas_inst=piezas.instance()
piezas_inst.set_name("Piezas")
add_child(piezas_inst, true)
pass
Just do the steps in a deferred way.
You can also do that indeed, but beware of the .free() on the node, you can’t call this at anytime unless you know what you’re doing
Zylann | 2017-01-27 18:10
its better to use queue_free, when u use free i could cause an crash. i think when something is accessing it for example.
ingo_nikot | 2017-01-27 18:19
Yep. The node will hang out for a frame when you queue_free(). So it keeps it’s name in the scene tree until it’s cleaned up, the deferred call is a good way around that.
avencherus | 2017-01-27 19:41
You can check the RID too, but the best is not to rely on a name, use a group instead, that will be always the same, and use index -1 for the last element just in case the first was not removed yet.
eons | 2017-01-27 21:04
@Zylann, @ingo_nikot: According to documentation, call_deferred is executed on idle time, so there is not risk calling to free(). See Singletons example.
@eons: groups is an option if I only want to remove the code and insert the new one, but I need to access the rest of the members of the node in other parts of the code for what groups is not an option.
func _on_Button_pressed():
get_node("Piezas").set_name("PiezasFreeing")
get_node("PiezasFreeing").queue_free()
var piezas=load("res://piezas/escenas/piezas.tscn")
var piezas_inst=piezas.instance()
piezas_inst.set_name("Piezas")
add_child(piezas_inst)
That solution simply works and it is the obviously solution! Aye!