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?
1 Answers
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:
- Changing the order of the
Node
s in the scene tree, of course. - You can use a
YSort
to haveSprite
s and otherNode2D
draw in a order based on theiry
position. - You can use
z_index
on aNode2D
to make things draw further above or below than they would other wise. As alternative, you can useVisualServer.canvas_item_set_z_index
which also works withControl
s. - You can use
show_on_top
andshow_behind_parent
on aCanvasItem
(Node2D
orControl
) to have it show on top or behind its parentNode
. - You can organize your elements in
CanvasLayer
s which are drawn in the order of theirlayer
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).

- 31,890
- 5
- 57
- 86