Adding offset, to fire a projectile relative to character

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Paulix

Im trying to create some kind of a bullet hell game, but first I want to be able to create a projectile that will be pretty flexible. Here is my projectile script atm:

extends Node2D

var dir = Vector2(1, 1)

export var bullet_speed = 200

func _ready():
    pass

func _process(delta):
    self.position += dir * delta * bullet_speed

func create_bullet(direction, spawnpos, offsetX = 0, offsetY = 0, ignoreoffset = false):
    spawnpos.x += offsetX
    spawnpos.y += offsetY
    self.position = spawnpos
    dir = direction

And my character is currently using this method to “fire”:

func _process(delta):
    if (Input.is_action_just_pressed("Shoot")):
	    var bullet = Bullet.instance()
	    bullet.create_bullet(Vector2(
		    get_global_mouse_position().x - self.position.x, 
		    get_global_mouse_position().y - self.position.y).normalized(), 
		    self.position, 50, 50)
	    get_parent().add_child(bullet)

The problem is, once I pass the parameters “50, 50” to the offset, the offset is “fixed” to the character, but I needed the offset to be relative to the position the player is looking, to make it spawn from a different place in case a different creature is shooting.
For example if my character uses like 2 cannons, I would need to fire it slightly offset to the left and right to match the sprite, but the “offset” would need to rotate with the player.
I know that my create_bullet method, I would need to make something else than adding offset to spawnpos, but since its math based, I dont know how to solve this.

:bust_in_silhouette: Reply From: AlexTheRegent

You are adding offsets in global coordinates, and your offsets are in local. So your problem is that you need to convert local coordinates to global. Since you already have normalized direction vector, you just have to multiply it by offset values to make them global:

spawnpos.x += direction * offsetX
spawnpos.y += direction * offsetY

I manage to solve using this:
self.position += Vector2(offsetX, offsetY).rotated(pos.angle_to_point(direction))

thx for your help btw, made me go in the right direction

Paulix | 2021-07-17 20:25