So, if anyone else stumbles across this post and wonders how I fixed it… Well I ended up completely changing the way the “gun” handles aiming and accuracy.
So if you are looking for a way to have a 2D gun or projectile firing weapon aim and fire, here is how I did it:
First, the weapon has an Area2D node that gives it its range, and it uses that range area to look for targets, and then find the closest target.
The code for this looks like this:
First I stored all the targets in range in an array:
func findEnemies():
var enemies = []
var bodies = $Area2D.get_overlapping_bodies()
for body in bodies:
if body.is_in_group("Enemy"):
enemies.append(body)
Then I used this code to look for the closest enemy.
func findClosestEnemy():
var closestDistance = INF
var closestEnemy = null
if enemies.size() > 0:
for enemy in enemies:
if enemy != null and enemy.is_in_group("Enemy"):
var enemyHealthNode = enemy.get_child(1)
if enemyHealthNode.currentHealth > 0:
var distance = player.global_position.distance_to(enemy.global_position)
if distance < closestDistance:
closestDistance = distance
closestEnemy = enemy
Once I had the closest target, I could then use this code to rotate the gun/weapon to look at the target.
You can use the lerp() function to control how fast you want the rotation to happen, so mess with the final value to get the feel you want.
if closestEnemy:
#find position of closest enemy
var targetEnemy = closestEnemy.position
#get vector from self to enemy
var v = targetEnemy - global_position
#get angle of vector
var angle = v.angle()
#get current rotation
var r = global_rotation
#get angle to target
angle = lerp_angle(r, angle, .06)
#set rotation
global_rotation = angle
**Also, my initial desire was to use the mouse position as the target, and I forgot to mention that this is still possible with this code! Simply replace the first two lines of code from the block above with the following:
#get mouse cursor position
var mousePos = get_global_mouse_position()
#get vector from self to mouse position
var v = mousePos - global_position
So all that handles rotation to look at the target, but it does not handle accuracy! How did I do that you ask? Well, I ended up modifying the way the projectile fired by the gun spawns to control the accuracy.
Here is how I did this:
#variables
var accuracy = .1
var currentAmmo = 30
func shoot():
if currentAmmo > 0:
var b = Bullet.instantiate()
owner.add_child(b)
b.transform = $Barrel.global_transform
b.rotation += randf_range(-accuracy, accuracy)
The $Barrel node in this code is a Marker2D placed at the end of the barrel of the weapon’s sprite, basically to function as a point where the projectiles spawn. by adding in the randf_range() it randomly changes the direction of each bullet as it is fired, giving us the desired accuracy based on the accuracy variable!
There are other ways of doing this, as I am sure some more experienced programmers can tell you, but this method worked for me and allowed me to figure out a lot of how you can rotate things to look at other things.
I hope this is able to help you if you needed it!