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