+1 vote

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:
Project Layout
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:
Picture of what I want to happen
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
radius - pre-defined radius
rotation - rotation in radians

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.

in Engine by (48 points)

3 Answers

+4 votes
Best answer

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

world.add_child(bullet)
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 :)

by (186 points)
edited by

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

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

+2 votes

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 shotscene = preload("res://bullet.tscn")
var shotspeed = 1000.0

func fire():
     var shot = shotscene.instance()
     var shotvect = (get_node("shotpoint").get_global_pos() - get_global_pos()).normalized()
     get_parent.add_child(shot)
     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. 
by (543 points)
edited by

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
          get_parent().add_child(shot)
          shot.set_global_pos(pos)
+2 votes

I have found a slightly more elegant solution to this than the 'shotpoint' method described above.

This is assuming your turret is facing "down" while at 0 rotation (from the orientation of Mr Godot in your screenshot that seems to be the case)

var barrel_length = 32   # Adjust as needed
var trans = get_global_transform()
var bullet_pos = trans.basis_xform( Vector2( 0, barrel_length ) )

Bullet_pos could also then be normalized, and re-used as the directional vector the bullet travels along.

by (1,328 points)
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 [email protected] with your username.