04M04
04M04

Reputation: 3

Godot 4.1 global_position is offset. Why?

If i use the player position to position the laser I get the laser in the origin of the player like I want it to be. Unfortunately I need the players global_position for positioning the laser. But everytime I try this it gets offset to the right and down. Why does this happen.

I have setup a demo image of some code and the result. Both lasers should be at the same spot but the second which uses global_position is not at the origin of the player.

enter image description here

enter image description here

enter image description here

I tried to find the root cause but I didn't get it.

Both lasers should overlap in my understanding.

update: Now I tried this: "laser2.global_position = $Player.global_position" but it also did not work. I get the same result as with "laser2.position = $Player.global_position".

The reason why I use global_position is because I want to spawn the laser at the top of the gun with a Marker2D. I will get the position to spawn via Marker2D.global_position in the player node. Then I spawn the laser in the Level via the position = global_position of Marker2D.

Like in this tutorial https://youtu.be/nAh_Kx5Zh5Q?t=11008

Upvotes: 0

Views: 2982

Answers (4)

user23165265
user23165265

Reputation: 1

Chiming in here to say I had the same issue as Cole Flicek. the "scale" parameters of my root "Level" node of my level somehow got changed from the default (1,1) and it was making the laser position offset from my player character sprite when using the global_position.

Upvotes: 0

Cole Flicek
Cole Flicek

Reputation: 1

I know this is an old question but I'm currently working on the same tutorial and had the same thing happened.

What fixed it for me is that at some point the base Node2D for my level scene got moved and when I reset the X & Y for that node to 0, 0 the global_position worked as in the video.

Hope this helps some future learner.

Upvotes: 0

Theraot
Theraot

Reputation: 40295

The code in the linked image says:

laser.position = $Player.position
add_child(laser)

In this case, the code is running in both the parent of $Player (since you can get it with this syntax) and laser (since you are adding it as a child).

So $Player and laser have the same local coordinates (they both have the same coordinates respect to their parent because they have the same parent).

Therefore using position here is OK.


The code in the linked image also says:

laser2.position = $Player.global_position

Here you are setting the position of laser2 relative to its parent to be equal to the position of $Player relative to the world origin. Those are not the same origin, and we cannot trust this will work.

If this does not work it is because the parent (the Node that has the Script attached) is not in the world origin (or has some scaling or other transformation applied).

Instead it is safe to work with global coordinates, like this:

laser2.global_position = $Player.global_position

Except you would have to do it after adding the new Node:

add_child(laser2)
laser2.global_position = $Player.global_position

Another option is to convert the global_position to local coordinates with to_local:

laser2.position = to_local($Player.global_position)
add_child(child_sprite)

In your case, you do not need to do this, since as explained at the start the local coordinates match (so you can directly set position). However, in other situations different from your current one, this might be useful.

Upvotes: 0

mourad
mourad

Reputation: 687

not 100% certain but maybe the origin of the laser is the position of the first point of the collision shape you drew around the player?

:-)

Upvotes: 0

Related Questions