Search code examples
godotgdscript

Godot: Create instanced scene (texturebutton) and make it come to the foreground


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?


Solution

  • 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 Nodes in the scene tree, of course.
    • You can use a YSort to have Sprites and other Node2D draw in a order based on their y position.
    • You can use 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 Controls.
    • You can use show_on_top and show_behind_parent on a CanvasItem (Node2D or Control) to have it show on top or behind its parent Node.
    • You can organize your elements in CanvasLayers 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).