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.).