I'm new to programming in Godot but I've been playing around with things I've learned in various tutorials. That is, until I ran into the following issue which I can't seem to debug. I attached a video to show what's happening.

When I first run it, the child bullets work really well with the position at the Gun's Marker2D, direction and rotation according to the code. Once I move the player though, the global_position of the Marker2D seems to translate in the same Vector as the player movement but greatly increased. So rotation and direction still work fine, but the starting position is way off. It's even possible to move back to the original pos and then the bullets start at the right place again.

Code at player.gd:

extends CharacterBody2D

const SPEED = 400

var bullet_scene: PackedScene = preload("res://projectile.tscn")

func _process(_delta):
    var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
    velocity = direction * SPEED

    if Input.is_action_just_pressed("primary_shot"):
        var weapon_rotation = (get_global_mouse_position() - position).normalized()
        var shot_pos = $Gun/Marker2D.global_position
        var other_rotation = get_angle_to($Gun/Marker2D.global_position)
        #print("shot_pos:", shot_pos, "weapon_rot:", weapon_rotation)
        var bullet = bullet_scene.instantiate()
        bullet.position = shot_pos
        bullet.direction = weapon_rotation
        bullet.rotation = other_rotation

For some reason, if I emit a signal from the player with all the same variables to my main.gd, and run everything verbatim from var bullet onwards in its signal function, it works just fine. My concern is that I literally have another project I made a couple of days earlier where I run everything in player.gd and it works perfect there, but not now, and I want to know what I'm doing wrong.



1 Answer 1


You are mixing coordinates spaces.

Here is the issue at hand:

var shot_pos = $Gun/Marker2D.global_position
# (...)
bullet.position = shot_pos

The variable shot_pos is in global coordinates, but you set position which is relative to the parent (of the bullet in this case, i.e. get_node("Projectiles")). Set global_position instead.

You might be interested in: Why isnt my spike shooters child showing up in the scene in godot?

I believe the direction is not presenting any issues because you are not rotating the player character. Yet, it is also mixing coordinate spaces:

var weapon_rotation = (get_global_mouse_position() - position).normalized()

As the name suggest get_global_mouse_position() is in global coordinates. Meanwhile position is not, instead it is relative to the parent (of the character body in this case). Use global_position.

An slightly different issue can happen with the rotation. Because get_angle_to takes global coordinates and converts them internally, the rotation is correct... for the character body where you are calling it.

If there is any rotation introduced between the character body and get_node("Projectiles") it would not behave correctly.

A solution could be to take the rotation at get_node("Projectiles") which is where you are adding the children:

var other_rotation = get_node("Projectiles").get_angle_to($Gun/Marker2D.global_position)
  • \$\begingroup\$ Thank you so much for your answer!!! I've been searching a lot and this is the first time I'm reading about issues involving mixing coordinate spaces. Your answer helped clarify this and I'm very happy to be able to move on after days of trying to debug this. Thanks again! \$\endgroup\$ Commented Jan 21 at 4:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .