You can put this code where you need it and where there is a raycast as a child (in my example I refer to it as a 'detector'). Then you set another scene apart for the dialog box and save it, in my case, it's a Node2d with a Label and a ColorRect as children (you can use RichTextLabel). The idea is to instantiate this scene as many times as necessary, but in order to later eliminate them I use an array to save each new instance.
1- Create a temporary variable and instantiate the dialog box:
var p = pop_up.instance ()
2-Access the text property of the Label node (which is child of the dialog box and in my case it is called TextLabel) and I assign it a string and use the native function str () to convert a variable to string and concatenate with the operator + (You can use any valid variable):
p.get_node ("TextLabel"). text = "Hello" + str (object.name)
3-Access the position property of the dialog box (node2d is the parent) and assign the same position of the object that detected the raycast plus about -30 pixels on the Y axis: p.position = object.position + Vector2 ( 0, -30)
4-If the array has a size greater than 0 it means that there is already another dialog box in the scene, so, I use the position of the last dialog box in the scene plus about 30 px on the x-axis. (You can access the last object that has an array with my_array.back ()):
if (dialog.size ()> 0):
p.position = dialog.back (). position + Vector2 (30,0)
5-add the instance of the dialog box as child of the current scene:
add_child (p)
6-Use the array to save that reference, since when creating a new var p, the previous reference is lost:
dialog.append (p)
7- outside the if statement of the raycast, I delete the last position of the array (the last dialog box created), if the ESC key is pressed and if the array has elements. Unlike back () that returns the last position of the array, popback () first returns and then deletes the last element in the array. Then I can use queuefree () to delete the reference (The last dialog box created):
if(Input.is_action_just_pressed("ui_cancel") and dialog.size() != 0):
dialog.pop_back().queue_free()
Any questions, ask me and sorry if my English is bad.