How do i toggle visibility in arrays?

Godot Version

4.6

Question

i want to enable the visibility of a texture rect with the corresponding color to the block that is being deleted

extends Node3D




func _on_timer_timeout():
	
	var red_nodes = get_tree().get_nodes_in_group("red block")
	var blue_nodes = get_tree().get_nodes_in_group("blue block")
	var green_nodes = get_tree().get_nodes_in_group("green block")

	var all_candidates = []
	all_candidates.append_array(red_nodes)
	all_candidates.append_array(blue_nodes)
	all_candidates.append_array(green_nodes)
	
	
	if all_candidates.size() > 0:
		var color = all_candidates.pick_random()
		color.queue_free()
		print("Deleted block: ", color.name)
	else:
		print("No more colored blocks left!")


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass

picture https://imgur.com/a/gdOBpZD

Ok, you want a function and you have a code. And what’s the result of your code that is different than your expectation?

1 Like

I would find the size of the ‘all_candidates’ array once the ‘red_nodes’ are in, then find the size increase when the blues are appended, then the size again when the greens are added. Any random number in the ‘red’ range is a red block, a number in the blue range is blue, and a higher number is green. All this assumes no sorting of the array once it ahs been composed.
Hope this helps; there may be better methods, but that’s what I’d try.

What about using a Dictionary with color as key and value the array? You can pick two random values, one for the color and the other for the element. Or one array of an structure containing color and array in case you want to make a direct pick, you will have color and content on the same element.

1 Like

The easiest way I can find (but you may need optimizing) by looking at your code, is creating the all_candidates array each time the $Timer ticks filtering out visible nodes. Also you make a 2nd array of just the 3 colors. So basically pick a random node and random color. You don’t need to deal with crazy parallel arrays nor delete a node which with arrays is crazy because they are created by reference. Here is the code (mind you i’ve changed some variable names):

extends Node3D

func _on_timer_timeout():

	var all_candidates = [] 
	var red_nodes = get_tree().get_nodes_in_group("red")
	var blue_nodes = get_tree().get_nodes_in_group("blue")
	var green_nodes = get_tree().get_nodes_in_group("green")
	var arr=green_nodes+red_nodes+blue_nodes
	for n:Node3D in arr:
		if !n.visible:
			all_candidates.append(n)
		pass
	
	var all_colors=[Color.RED, Color.GREEN, Color.BLUE]

	if all_candidates.size() > 0:
		var texture: Sprite3D=all_candidates.pick_random()
		texture.visible=true
		texture.modulate=all_colors.pick_random()
		prints("Marked block: ", texture.name)
	else:
		print("No more colored blocks left!")
		$Timer.stop()


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass