global positioning is a miracle to me.... can't tween a collectable to the HUD position

Godot Version

4.5

Question

the debug print is showing me that my score / hud is at position (16.0,16.0). my collectables are spread over the scene. each collectable is showing via the debug print no difference between the position and the global_position, i.e (328.0, -832.0). my project display window size is set to 1020x640.

my hud is implemented as a global autoload scene as a node2d which incorporates the score scene. the score scene is a canvas layer node.

the collectable node(s) is a / are animatedsprite2D

this is my collectable gd script:

extends AnimatedSprite2D

var scorePos

func _ready() -> void:
	scorePos = get_tree().current_scene.get_node("/root/GameManager/Score/Display/notesIcon").global_position

func _on_area_2d_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		
		print("note (global): ", global_position)
		print("score: ", scorePos)
		
		GameManager.playSoundFX(load("res://assets/sounds/note.mp3"))
		GameManager.game_notes += 1

		var tween = get_tree().create_tween()
		tween.tween_property(self, "global_position", scorePos, 1.0).set_ease(Tween.EASE_IN)
		tween.chain().tween_property(self, "visible", false, 0.0)
		tween.chain().tween_callback(queue_free)
	pass

as i am struggling now for more or less day, i felt like better to ask… hm, my best guess is that the collectable position / global position should be different values…. where i assume the global_position should “match” the score global_position value logic…. do i need to transform the coellectable position into a global position coordinate? if so, how can i achieve this?

plase help, any tip, trick would be very much appreciated!!!

What’s the problem precisely? They don’t end up at wanted position when tweened?

yep, the fly around someplace …

Maybe assign that scorePos just before starting the tween.

I don’t use GDScript much, but I think what the problem might be is that you need to “translate” the position in the game world into a position on the control nodes of your HUD.
In C# I achieved this with the following function, and I assume it’s easy to do the same in GDScript, see if that helps:

public static Vector2 WorldToViewport(Node2D target)
{
    Vector2 targetCanvasPosition = target.GetScreenTransform()
        .Origin.Clamp(Vector2.Zero, target.GetViewportRect().Size);

    return targetCanvasPosition;
}

no, did not do any difference…

If a canvas layer is in the hierarchy then global_position will be in its coordinate system. Try to multiply it with canvas layer’s transform.

score (hud) is /has a canvas layer. the collectable is made of animated2d - aread2d - collisionshape2d. do you mean to add a canvas layer to the collectable?

scorePos = canvas_layer.transform * scorePos

		scorePos = get_tree().current_scene.get_node("/root/GameManager/Score/Display").position
		scorePos = scorePos.transform * scorePos

this is the error code i get:

Invalid access to property or key ‘transform’ on a base object of type ‘Vector2’.

where do i get the “canvas_layer” from. tried with : @onready var score: CanvasLayer = $“.” but then brings up the error message:

Trying to assign value of type ‘AnimatedSprite2D’ to a variable of type ‘CanvasLayer’.

You get it via a path to whichever node is the canvas layer in your hierarchy.

good morning, i did some more testing by adding a sprite2d to the scene and let the collectable tween to that position… it works perfectly….

my remote tree is showing 3 nodes: GameManager, AudioManager and my scene called Wonderland. the score / hud is with the node GameManager. for my logic: this is causing the pain…. how to i get the correct position from the gamemanager score into the wonderland? any idea?

i did approach the problem differently by getting the viewport world coordinates. now the tween works as expected… thank you for your help, anyway… very much appreciated.

func print_viewport_corners():
var viewport = get_viewport()
var canvas_transform = viewport.get_canvas_transform()
var viewport_size = Vector2(viewport.size)
var top_left = canvas_transform.affine_inverse().origin
var bottom_right = canvas_transform.affine_inverse() * viewport_size

print("Top left corner (world coordinates):", top_left)
print("Bottom right corner (world coordinates):", bottom_right)

return top_left
var canvas_layer = get_node("/root/GameManager/Score")
scorePos = get_node("/root/GameManager/Score/Display").global_position
scorePos = canvas_layer.transform * scorePos