# Godot Top-Down Shooter, getting a bullet to fire from a rotated gun?

Attention Topic was automatically imported from the old Question2Answer platform.
Old Version Published before Godot 3 was released.

Okay, so I’m currently creating a top-down shooter with weapon switching, I’ve come across a problem.

First up, this is the layout of my player:

This is what I came up with, sprite is rotated to “look_at” the mouse position, then the gun is a child of the mouse so it’s rotation is changed too.

Now I want to fire a bullet from a gun, so I came up with this:

Basically I want to find a point on a circle.

So I used the following equations:

x = centreX + radius * cos(rotation)
y = centreY + radius * sin(rotation)

In this line of code:

var posOnCircle = Vector2(pos.x + radius * cos(rotation), pos.y + radius * sin(rotation))

pos - centre of player

And this doesn’t work for me. Maybe I’m overcomplicating things, I’d be satisfied with a better solution to the problem rather than just a fix, but this is what I came up with.

Well this should work quite nice for your needs, I hope:

var rotation  = self.get_rot()
var direction = Vector2(sin(rotation), cos(rotation))
var distance_from_me = 100 #need to best adjusted by you
var spawn_point      = self.get_global_pos() + direction * distance_from_me
var bullet = bullet_scene.instance()
var wolrd  = self.get_node("../world") #of wherever you're bullet should spawn, but don't spawn it as a player child

bullet.set_global_pos(spawn_point)

You can then also pass the direction vector to the bullet, to use that as the movement for it in the _process(dt) function.
Note: Maybe you need to add PI/2 or something like that to the rotation variable if the bullet spawns in the wrong angle of your player if for example your sprite has any base rotation applied to it.

Hope that helps

I don’t know anything about cos and sin but i used Vector2(cos(rotation), sin(rotation)) and it works but your doesn’t works

Chisk3n0 | 2019-01-01 00:08

Thx Chisk3n0. I figured it out the same and then saw you comment (confirming this).

Naxos84 | 2020-04-19 23:17

I just use a Node2D “shotpoint” as both the spawn point for the bullet, and as a target position to calculate the shot’s direction vector. Assuming you want to fire your bullet on a vector straight from the origin of this node, you do:

var shotspeed = 1000.0

func fire():
var shot = shotscene.instance()
var shotvect = (get_node("shotpoint").get_global_pos() - get_global_pos()).normalized()
shot.set_global_pos(get_node("shotpoint").get_global_pos())
shot.set_linear_velocity(shotvect * shotspeed) # if your shot is a rigidbody

# If your shot is not a rigidbody and handles movement itself, set a velocity var
# on the shot before you add it to the scene so its ready() function fires after it is set.

If you want to make a shotgun or any weapon that shoots multiple bullets in different directions, I’ve done it two ways:

A. Just move the “shotpoint” node (probably by rotating its parent) and call fire() again.

B. Iterate through multiple “shotpoint” nodes. Name them “shotpoint 0”, “shotpoint 1”, etc. Adjust the fire() function as follows:

var shotcount = 5 # as many as you want, as long as you have enough shotpoint nodes.

func fire():
for i in range(shotcount):
var pos = get_node( "shotpoint " + str(i) ).get_global_pos()
var shotvect = (pos - get_global_pos()).normalized()
var shot = shotscene.instance()
shot.velocity = shotvect * shotspeed
shot.set_global_pos(pos)

rgrams | 2016-09-08 11:28