I have this all sorted out, except my instanced buttons show up on what appears to be the lowest layer. My map (texturerect) is drawn above them. How can I, through code, direct Godot to draw these new buttons on top of a specific node?
In 2D, by default, the draw order is the scene tree order. Things closer to the top of the three are drawn first. Children are drawn after/on top of their parent Node
.
You can manipulate this order in multiple ways. For example:
Node
s in the scene tree, of course.YSort
to have Sprite
s and other Node2D
draw in a order based on their y
position.z_index
on a Node2D
to make things draw further above or below than they would other wise. As alternative, you can use VisualServer.canvas_item_set_z_index
which also works with Control
s.show_on_top
and show_behind_parent
on a CanvasItem
(Node2D
or Control
) to have it show on top or behind its parent Node
.CanvasLayer
s which are drawn in the order of their layer
number.It is that last one which is often suggested to separate UI from the game world. Have a CanvasLayer
for all your UI items, and another CanvasLayer
for your game world. Another feature of doing this is that a Camera2D
placed inside a CanvasLayer
does not affect the others. So the UI can stay in place regardless of the game world camera moving - which is useful for HUDs - for example.
Another thing I'm going to suggest is to not manipulate the UI directly from the game world. Not only because it makes organizing the UI awkward, but because it means that updating the UI requires to modify the game world code (i.e. changing the appearance of the game requires changing the behavior of the game). Instead have the game world code emit signals when you need to update the UI, and receive those signals where it is appropriate to update the UI. Furthermore, you can route all the signals through an autoload (i.e. a signal bus/event bus).