get_global_position() not working right?

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

Hello, I am trying to shoot a cannon ball from the tip of a cannon. I have a position2d
at the end of the barrel. I have a simple function that starts the ball there. However when
I try to place the ball at the global position of the muzzle you can see what happens from the image. I am setting the ball at the global position of the muzzle which is nowhere near where the balls are being placed. Is this perhaps a bug?

are you taking the GLOBAL position of the position2D node? or just the position?

rustyStriker | 2018-02-28 10:33

did you place it at the global position of the cannon? I think it should be at position2d’s position.

asetyowatir | 2018-02-28 13:11

Can you provide code or project? I’ll have a quick look.

Footurist | 2018-02-28 13:14

@Footurist I moved your answer to comment.
please use “Comment” if it’s not an answer to question.

volzhs | 2018-02-28 13:43

Ok, sry I will try to remember it!

Footurist | 2018-02-28 14:06

the orange square position2d at the bottom is the parent node that is the hinge(called swivel) so to speak and the muzzle is the position2d at the end of the barrel.onready var muzzle = $swivel/area/muzzle" then I am going muzzle.get_global_position() to get the position 2d. I have tried just muzzle.get_position() and that actually put the cannonball next to the muzzle closer but would not change the spawn point when I rotated the barrel.
I have no nodes or parent nodes somewhere else in the scene. Also I checked the output of printing the global position of the muzzle variable and it appears to give the global position of the muzzle position2d when I rotate the barrel around.

I used to have another scene in this project that I deleted to start over and it used to give me a little problem when I started godot saying: “Can’t find scene cannon…scene” But since I changed the main scene godot has not been giving me that message. I have no extra folders or scenes in my godot root directory but I don’t know maybe there is some unseen artifact.

godotbot | 2018-02-28 19:47

I will gladly provide project but I don’t know how on this forum.
The formatting is wrong for some reason I used the code tags. Note it is taking out the underscores that were originally there.

Here is the code for the cannon scene:

extends Area2D

var swivel_rotation = 0.0

var increment = 1
var swivel_limit = 1.1
var recoil_blast_speed = 130
var recoil_return_speed = 20
var is_recoiling = false
var returning_barrel = false

onready var cannon_ball = preload(“res://scenes/cannonball.tscn”)
onready var cannon_ball_container = $cannon_ball_container
onready var muzzle = $swivel/area/muzzle
onready var swivel = $swivel

func _process(delta):

print(str(swivel.get_rotation()))
print(str(muzzle.get_global_position()))

if Input.is_action_pressed("ui_right"):
	if swivel_rotation < swivel_limit:
		swivel_rotation += increment * delta
		$swivel.set_rotation(swivel_rotation)
if Input.is_action_pressed("ui_left"):
	if swivel_rotation > -swivel_limit:
		swivel_rotation -= increment * delta
		$swivel.set_rotation(swivel_rotation)

if $swivel/area.transform[2].y <= -50: # see if reset first
	if Input.is_action_pressed("ui_select") && is_recoiling == false:
		is_recoiling = true
if is_recoiling == true:
	if ($swivel/area.transform[2].y <= -25) && (returning_barrel == false):
		$swivel/area.transform[2].y += recoil_blast_speed * delta
		if $swivel/area.transform[2].y >= -25:
			returning_barrel = true
	else:
		$swivel/area.transform[2].y -= recoil_return_speed * delta
		if $swivel/area.transform[2].y <= -50:
			$swivel/area.transform[2].y = -50
			returning_barrel = false
			is_recoiling = false
if Input.is_action_just_pressed("ui_select"):
	shoot()

func shoot():
var c = cannon_ball.instance()
cannon_ball_container.add_child(c)
c.start_at(swivel.get_rotation(), muzzle.get_global_position())

Here is the code for the cannon ball itself:

extends Area2D

var vel = Vector2()
export var speed = 200

func start_at(dir, pos):
set_rotation(dir)
set_position(pos)
vel = Vector2(speed,0).rotated(dir-PI/2)

func _process(delta):
#set_position(get_position() + vel * delta)
pass

godotbot | 2018-02-28 19:54

try set_global_position instead of set_position in the startat function

rustyStriker | 2018-03-01 16:48

Yes that worked. Thankyou rusty. It is very confusing though because I used this same code in a tutorial and it used the “start_at” function only with set_position() and then it passed in a get_global_position() into the function and it worked just great. Now I am using get_global_position() and set_global_position()and it works.

godotbot | 2018-03-01 20:20

position is relative to the parent, that means that if your node is at (10,10) and you place a child node on him at (20,20) the global_position of the child node will be (30,30), they might have set the parent node in the tutorial to (0,0) so it will be the same as the global_position

rustyStriker | 2018-03-02 11:46