How to change property of all nodes inside a group

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

Hello, my scene has too many Lights2D nodes, and that slows down the performance of the game. To solve the problem, I divided Lights2D nodes into different groups, so when player is not in a zone, the Lights2D will be turn off to improve performance. I am having problem to set property of enabled, not sure what to put down to define enabled property. So could some one kindly advise how to change property for all nodes inside a group? Thank you.

func switch_off():
	???.enabled = false


func _on_Switch01_body_entered(body):
	if body.name == "Player":
		get_tree().call_group("LightSection_01", "switch_off")
:bust_in_silhouette: Reply From: djmick

You could use a for loop to iterate through all elements of a group, like this:

func _on_Switch01_body_entered(body):
     if body.name == "Player":
          for light in get_parent().get_nodes_in_group("LightSection_01"):
               light.switch_off()

Hopefully this helps!

Thanks for answering my question. My problem is that, I have many lights nodes in the group, not sure what to put in to replace the ??? part in the switch_off function.

However, after some research, I found out that instead of using call_group, I should use set_group to set the property. When I switched to the following code, it works.

   if body.name == "Player":
		get_tree().set_group("LightSection_01", "enabled", false)

Idleman | 2021-01-27 00:54

:bust_in_silhouette: Reply From: Idleman

After some research, I found out that instead of using call_group, I should use set_group to set the property. When I switched to the following code, it works.

   if body.name == "Player":
		get_tree().set_group("LightSection_01", "enabled", false)
:bust_in_silhouette: Reply From: fagnerln

It’s nice that you found a solution, but I think that there’s easier ways to do that.

If those lights have a script attached, IMO callgroup is better as you call a function, so inside that function you can define a lot of things, not only enabled.

But why are you working with groups in this situations? I suppose that it’s predefined, so I think that would be a lot easier to work with sub nodes. Create a node that groups the section and create a simple loop

for i in $LightSection_01.get_children():
    i.enabled = false

Thank you so much for takin time to answer my question. Your suggestion works nicely without the need to work with group. One quick question, you mentioned that it would be a lot easier to work with sub nodes than groups. Besides the extra work to add lights into groups, is that any other benefit to use sub nodes instead of groups. Does it cost more performance when working with groups? Thank you.

Idleman | 2021-01-27 05:18

I think that you need to test for yourself, I think that there’s no difference performance wise, but who knows?

I don’t think that put a node inside a node is harder than put nodes in a group.

If you put a light in a scene, you will need to set the group individually, but if you keep the parent node selected it automatically set the node as child.

If you forgot to put the light in a group, you need to search manually, but if you use nodes, just click on hide and you will see what are the children.

If you want to create lights via code, you need to set the group before add it as child, and to put on the parent node is simple as

$LightSection_01.add_child(newlight)

I’m not telling that you should use it this way, it’s just a opinion, do whatever you feel more comfortable, if you think that’s easier to use groups, go ahead!

fagnerln | 2021-01-27 05:37

Thanks for sharing your point of view, I am new to Godot and this is the first time I have a need to use groups, so I try to learn more about pros and cons of different approaches to solve a problem.

I will go with the sub node method, since I have already sorted the nodes of lights into hosting node, so it is easy to use loop. Setting up groups require more works and the way of how group works, sometimes it is difficult to keep track which node is in which group.

Thank you for your reply.

Idleman | 2021-01-27 06:06

I’m glad that it helps, I’m new too and always trying new method to create a logic.

Groups are interesting if you don’t know who casted it, for example enemies bullets, as the bullets are child from different node enemy, is preferable to add every bullet to a group, so you manages it directly from the tree, so you can destroy all of it.

In this example you still can group it with nodes, supposing that every enemy are a child of a level scene, with a node called bullets to hold every shot, so every shot should called as

get_parent().get_node("bullets").add_child(newbullet)

But isn’t recommended to do this as if the parent doesn’t has the node, it will break.

Sometimes is interesting to cast a bullet as a child of the parent, because if the enemy is dead, the bullet keeps going, but I don’t recommend to put inside a “brother” node.

fagnerln | 2021-01-27 11:41