how to delete a node (specifically a button) made through a for loop?

I tried making a JRPG prototype and the targetting system works sort of like the targetting system in deltarune. That is not really the problem, however.

Whenever the enemy the button is connected to dies, the enemy is no longer there, but the button still is. How do I tell the button to delete itself the moment the enemy is dead?

here is the for loop for more context:

for enemy_data in enemy_data_array:

#create the unit from the loop
var unit = battle_unit.instantiate()
var unit_button = Button.new();
unit_button.text = enemy_data.character_name;
unit_button.pressed.connect(unit.on_selected_pressed)
#add it (the units) to the screen
enemy_side.add_child(unit)
enemy_buttons.add_child(unit_button)

the if statement for when the opponent’s health is equal or below 0 is very simple:

  if enemy_unit.current_health <= 0:
  	active_enemy_units.erase(enemy_unit)
  	enemy_unit.queue_free()
  	print(enemy_unit)

(enemy_unit refers to the enemy being targetted and it is a PackedScene)
is there a way I can fix this? I had no problem erasing the unit and the data from the array for the enemies in battle but i’m stuck with the “deleting buttons upon death” part of the system.

Call queue_free() on the button as well, or parent the button to the enemy at instantiation.

Is unit_button the one you want to remove?

Because the unit you create has no reference to it, so how will it know what to call queue_free() on once it dies?

Can’t you add a property unit_button to your battle_unit scene and assign unit_button to it in your for loop?

This way, you can call enemy_unit.unit_button.queue_free() when the unit dies. (before calling enemy_unit.queue_free() of course)

If you don’t want to keep the buttons as children of the enemies, you could store references to them. I would do that with either an array or dictionary. If going for a dictionary, you could use the enemies themselves as keys and the buttons as values and then queue_free the value whenever a key dies. If you use an array you need to store a reference to both the enemy and the button, or have at least some way to get the right button for the right enemy.

var buttons_array: array

var iteration = 0

then in your foor loop, append the button to the array and after appending, increment iteration and with 1. So button for the first enemy will be on the first index of the array. Keep the iteration stored as a local variable in the enemy scene to compare with when enemy dies. Replace button with null in array, to not mess up indexes when you delete e.g. 2. Otherwise what was 3 will now be 2.

I’m sure there are many better ways.

I would definitely go for the dictionary in this case.

# property (you can type stricter if needed)
var enemy_buttons : Dictionary[Node, Node] = {}

# in your loop
enemy_buttons[unit] = unit_button

# upon death
enemy_buttons[enemy_unit].queue_free()
enemy_buttons.erase(enemy_unit)
enemy_unit.queue_free()

@baba 's dictionary solution may perform better. I like mine (1st one) too because it’s terse..