Position an object relative to visible screen

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

I’m trying to spawn a NinePatch to serve as a text box. However, since it’s a child of the Player node, it uses the player’s origin as its own. So, as soon as it’s added as a child, it

var talkbox = load("res://objects/talkbox.tscn") #This scene is the 9patch with its own script. 
var ibox = talkbox.instance()
#=== I have tried all of the options below, each by itself at a different time
ibox.rect_position = $playercamera.get_camera_screen_center()
ibox.rect_position = $playercamera.get_camera_position
ibox.rect_position = Vector2(position.x - 180, position.y + 100)

The problem is that they always spawn the box in a different place compared to the center of the screen.

Images of the problem

Is there a way to make a spawned node position itself relative to the visible screen? A gdscript function you can call?
I messed around with the 9patch anchor, but I couldn’t for the life of me get it to spawn where I need it to.

:bust_in_silhouette: Reply From: Andrea

you should make the controls node that do not have any link with the “world”, child of a CanvasLayer object.
This way those control nodes will always be in front of everything and their rect position will only depends on screen coordinates
Something like


:bust_in_silhouette: Reply From: Wakatta

Try changing the position after the add_child() function

#This scene is the 9patch with its own script. 
var talkbox = load("res://objects/talkbox.tscn")
var ibox = talkbox.instance()

#Add ibox instance to scene Tree

#get offset of ibox's size
var offset = ibox.rect_size() * vector2(0.5, 0.5)

#get screen center using viewport since camera size and position are not constant
var center = $playercamera.get_viewport_rect().size * vector2(0.5, 0.5)

#set ibox position to center of screen then offset by half of ibox's size
ibox.rect_position = center - offset