0 votes

Hello, I'm new to godot and programming. Problem is, I can not get my ship to fire. I have created a sprite-type node named "sprnaveshoots" that initialized in graph 2d with the parameter "visible" disabled. Then, in the parent script, create an empty array. When left-clicking the mouse, I have told godot that, this value is equal to the sprite "sprnaveshoots" with the difference that it will have the "visible" property activated. Once the sprite is stored inside the array, it will proceed to move the sprite, but when I try to get the position of the sprite and modify it, godot retorn me following error message: "Invalid get index '[Sprite: 563]' (Based on 'Array'). ".

These is my code:

 extends Node2D

    onready var nave = get_node("spr_nave")
    onready var nave_prt = get_node("prt_nave")
    onready var nave_shoot = get_node("spr_nave_shoot")
    onready var nave_shoots = []

    func _ready():

    func _process(delta):

    func move_shoot(shoot,delta):
        var sh = shoot
        var sh_p = shoot.get_pos()

    func mover_disparos_nave(delta):
        for i in nave_shoots:

    func disparar(delta):
        #var pos = nave_shoot.get_pos()
        #pos.y -=200*delta
        var disparo = nave_shoot
        var dis_pos = disparo.get_pos()
        dis_pos = nave.get_pos()

    func action_nave(delta):


in Engine by (15 points)

2 Answers

+1 vote
Best answer

Your for loop is not range-based, so here i is the sprite itself, not its index. You don't need to write nave_shoots[i]:

for shoot in nave_shoots:
    move_shoot(shoot, delta)

Alternatively, range-based for would look like this:

for i in range(0, nave_shoots.size()):
    move_shoot(nave_shoots[i], delta)
by (28,833 points)
selected by

Thank you very much! Now it works.

0 votes

If you look to the line you get the error, you may see the array is full of null objects (read errors, use breakpoints, analize variables and the tree).

I don't understand why but seems you can't assign an instanced node reference (from get_node) to an array, if you want to do that, use get_instance_ID on the node you got, then to recover the node with that id, do instance_from_id.

And pay attention that your shots will be working all on the same node, you are never duplicating or instancing new shots (look the platformer or shooter demos and read the docs for multiple instancing tutorials and explanations).

by (7,896 points)

Hi, you're right. Now I can shoot, but I'm working on the same node, and at the time of making a new shot, godot, puts it in the starting position. What I have to do is work with duplicate instances of the main node. I am right?

Yes, the best option could be to make a scene from the shot, then preload the shot on the ship.
Demos use this way and it works nice with export(PackedScene) var so you can choose the shot scene independent of the shot from the inspector.

Later, when you need a shot, just instance the preloaded, fix the proper global positions and other data and add the instance to the tree.
Careful where you add it, gettree().getroot() is viewport, next comes scene root where is the lowest node you should add them.

And more, to keep track of your shots (and also for detection filtering) you can use groups instead of arrays, just add every instanced shot to a group (as many groups as you need).

Finally, remember to delete the shots (time based, screen, with a visibility notifier, etc.).

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.