How can I come up with common names for multiple instancing.

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

When I instance a item the first time I want it to be called Item 1 then Item 2 and so on. But when I have Item 1, Item 2 and Item 3 then I pickup I Item 2 and then instance another item it should instance Item 2. My code that does not work:

onready var items = preload('res://items.tscn')

func add_item():
    var item = items.instance
    item.set_name('Items '+ str(get_node('Items').get_child_count()+1))
    get_node('Items').add_child(item)

If you try some test cases you will see that this system fails. I tried naming item the same thing but then the system makes the duplicate name into Item 1@some number increasing. I do not want the solution to involve a list storing all the names of the items. How could I solve this problem?

:bust_in_silhouette: Reply From: Zylann
var item = items.instance

Why is that not instance()?

The instance is getting a new name because you are adding it under a parent which already has a child with the same name. In Godot, child nodes must always have a unique name, so it’s getting auto-fixed to avoid further problems.

For your node to keep its name, it has to be added as child of a parent which doesn’t contain a node of the same name.

Or… add a member variable to your item script and store the actual name there, instead of relying on the node’s name, because node names obey to specific constraints.

Zylaan I understand what you are saying. I want code to find the name I should make the node. Can you please come up with some code I could use to come up with names with for my nodes?

jujumumu | 2019-08-18 22:52

Is it working if you do item.set_name('Items '+ str(get_node('Items').get_child_count()+2)) instead of +1?
In any case it’s because you end up with the same name as another node. Your method looks like a way to do this already but something else is acting up here.

Zylann | 2019-08-18 23:19

No you have the wrong idea this method will not work. If I have items 1,2,3 I take away 2, I have 1,3 then I ad using the code and it tells me to name the node 3 but it should name it 2 which is the gap. Basically when it adds fill in the gaps if there are none add another one.

jujumumu | 2019-08-18 23:37

Oh ok, I didn’t know you could take out items. Then I guess you could iterate from 1 to N and check if the name is available. If it is, use that name.

Zylann | 2019-08-18 23:54

Is that the most efficient method for doing this? And how would I implement this in code. The get_children function is kind of useless because it is like rigidbody2d:1994 instead of ‘Item 1’. If you find a solution please post it as a answer so I can upvote and check it. Thanks for answering a lot of my questions.

jujumumu | 2019-08-19 00:41

Like this?

func find_new_name():
	var items = get_node("Items")
	for i in range(1, items.get_child_count() + 1):
		var new_name = str("Item ", i)
		if not items.has_node(new_name):
			return new_name
	# Impossible to find a new name

Checking the names like this is the only way to go since you don’t want to use separate variables or data structures.
Otherwise a more efficient way is to keep a list of “free names” and pick from it when you need one, but then it adds complexity. You have to choose a balance, sometimes short code is more valuable than fast code.

Zylann | 2019-08-19 00:51

Thanks for the code. It works perfectly.

jujumumu | 2019-08-19 02:25