How can call a function on two nodes stored in array?

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

So I have two $Position2D nodes on a node to spawn projectiles on. They both have a script with a function to instance a ‘bullet’. This is how I currently call the function on my code:

func _shoot(): #shoot weapons
$Gun1._shoot_projectile(projectile)
$Gun2._shoot_projectile(projectile)

However, If i wanted to create an entity with more than two ‘guns’, I would have to copy and paste “$GunX.shoot_projectile(projectile)” for each ‘gun’ the enemy or player has. I tried doing this instead:

func _shoot(): #shoot weapons
for i in guns.size():
	guns[i]._shoot_projectile(projectile)

however, it doesnt work :). I also tried it by placing the ‘guns’ in groups but that would end up calling all guns of the same group across the entire project.

:bust_in_silhouette: Reply From: kidscancode

Since you said “doesn’t work”, but didn’t give any specifics, I can’t tell you what you did wrong. However, if you have a list of nodes, you can just loop through the list elements directly:

var guns = [$Gun1, $Gun2]

for gun in guns:
    gun.shoot_projectile(projectile)

Ok sorry, I though I did say what happened but i forgot. Specifically, nothing happened. No errors, nothing. I tried your solution but now its giving the error Attempt to call function '_shoot_projectile' in base 'null instance' on a null instance.

This error happened when I declared the ‘guns’ array in the same way as you. I tried using export instead and setting up the Position2D nodes in the editor and instead it gave me this error:Invalid call. Nonexistent function '_shoot_projectile' in base 'NodePath'.

Any other ideas?

Edit:
Out of curiosity I wrote ‘print(guns)’ and the console showed this:

[Object:null]
[Object:null]

wokeraccoon | 2021-06-04 06:10

I just showed that array as an example. I don’t have any idea how your nodes are arranged or how you’re putting them in the array. That part is up to you.

Exporting a NodePath gives a NodePath, not a node. You have to get_node() that node path to actually reference the node. That’s exactly what that error is telling you, you tried calling a function on a NodePath.

Plus, do you even need a separate array? Where are these Position2D nodes located? If they’re all under the same parent, you can use get_children() to get an array of them to begin with.

kidscancode | 2021-06-04 06:13

[This is how my nodes are currently set up] I tried using get_node(gun).shoot_projectile(projectile) instead but now I’m getting the error Invalid type in function 'get_node' in base 'KinematicBody2D (Player.gd)'. Cannot convert argument 1 from Object to NodePath. so I’m guess I’m using it wrong (I’m still kinda new to Godot and GameDev in general).

Also, I dont really understand how can i use get_children() to get those two Position2D on my Player tree

wokeraccoon | 2021-06-04 06:22

wait, I figured it out! I was missing the onready keyword on the guns array! Your for loop now works properly! Thank you!

wokeraccoon | 2021-06-04 06:26