Currently the Labels in the GUI are below the player and other objects, so the player appears above them. How can this be fixed?

extends Node
var load_1 = true

    onready var level = preload("res://scenes/levels/Level.tscn")

    var Level = null

    func _ready():
        Level = level.instance()

        move_child(Level, 0)
        VisualServer.canvas_item_set_z_index($GUI/Label3, 4000)
        print("I'm here")

    func _process(delta):

    func set_z_index(node):
        for N in node.get_children():
            if N.get_class() == "KinematicBody2D":
                N.z_index = N.position.y

    func getallnodes(node):
        for N in node.get_children():
            if N.get_child_count() > 0 and N.get_class() != "RigidBody2D" and N.get_class() != "KinematicBody2D" and N.get_class() != "StaticBody2D":

                if N.get_class() == "KinematicBody2D" or N.get_class() == "RigidBody2D":
                    print("- "+N.get_name())
                if N.get_class() == "StaticBody2D":
                    print("- "+N.get_name())
                elif N.get_class() == "Sprite":
                    print("- "+N.get_name())

    func setZOrder_kine(node):
        for N in node.get_children():
            if N.get_class() == "Sprite":
                var myPos = N.get_global_transform().get_origin()
                var mySize = N.get_texture().get_height()
                var bottomOfSprite = (mySize*N.get_scale().y * N.get_parent().get_scale().y)/(2 * N.vframes)
                N.get_parent().z_index = (myPos.y+bottomOfSprite)  

    func setZOrder(N):
        var myPos = N.get_global_transform().get_origin()
        var mySize = N.get_texture().get_height()
        var bottomOfSprite = (mySize*N.get_scale().y)/(2 * N.vframes)
        N.z_index = (myPos.y+bottomOfSprite)

    func _physics_process(delta):


            $GUI/Label.text = "Velocity: " + str(Level.get_node("Player").velocity.length()) + ", " + str(Level.get_node("Player").velocity.x) + ", " + str( Level.get_node("Player").velocity.y)
            $GUI/Label2.text = "Position: " + str(Level.get_node("Player").position.x) + ", " + str(Level.get_node("Player").position.y) + ", " + str(Level.get_node("Player").z_index)
            $GUI/Label3.text = "Sword: " + "rotation " + str(Level.get_node("Player").rotation)
            $GUI/Label4.text = "stamina" + str(Level.get_node("Player").stam.current) + "attack_charge: " + str(Level.get_node("Player").stab.charge.current) + "countdown: " + str(Level.get_node("Player").stab_countdown[0]) + "cooldown: " + str(Level.get_node("Player").stab_cooldown[0])

Rigid body above label 3, player above label 2


Well I've got an answer, create a node2d child node set its z index higher than all of the level's objects then make the GUI a child of the node2d. This well set it higher than the level objects.


Godot has Canvas Layers to solve this kind of problem.

They can provide high level control by keeping game elements on separate layers and managing which layers will be drawn in which order. Then within each individual canvas layer by node order or z-index can be managed as usual.

There is a handy tutorial in the official documentation that uses the following example:

  • Parallax background
  • Level foreground
  • Heads Up Display

enter image description here http://docs.godotengine.org/en/stable/tutorials/2d/canvas_layers.html


Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.