0 votes

Hi all. Just started my first project in Godot. Got a title screen and a selection screen. 3 days in and I'm off to a good start. Now I want to onboard people on the selection screen. I created a 50% opacity black full rect overlay. Above that is a tour guide that tells you what to click next. Everything below the overlay's z-index should be unclickable. No click events should pass through to buttons, etc. underneath. When the character tells you to click something, I want that object to move it's z-index above the overlay without changing any of its other behaviors. This way it's more visible, and it's clickable.

  • I'm using v3.2 in a 2D project with GDScript.
  • The overlay and all items I want to change the z-index for, are all children of the same control node.
  • Everything I have in mind is either a TextureRect or a Button.

So how do I temporarily change the z-index of my target, and then set it back to its original z-index once I'm done with it? Thanks.

in Engine by (22 points)

1 Answer

0 votes

Control-nodes don't have a z-index, check out this issue. You could add a CanvasLayer-node and reparent your control-nodes when you want to bring them to the front:

var control_node = get_node("<PathToYourNode>")
remove_child(control_node)
$CanvasLayer.add_child(control_node)
by (10,221 points)

Thanks for the guidance. I did this and it half worked. Progress! :) I'm re-parenting the child to a parent that has the same size and anchors as its original parent. When it's re-parented though, it moves to the left side of the screen. When I add code to move it back to its original location, it ignores that code. No error, just ignored.

if CLICKED:
    # ALL THIS WORKS
    var parentOLD = get_node("Selection_Screen/characters")
    var childMOVE = get_node("Selection_Screen/characters/heroA")
    var parentNEW = get_node("Top_Parent/new_top")
    parentOLD.remove_child(childMOVE)
    parentNEW.add_child(childMOVE)
    var childNEW  = get_node("Top_Parent/new_top/heroA")

    # THIS GETS IGNORED
    childNEW.set_scale(Vector2(.9,.9))
    childNEW.set_position(Vector2(260,28))

Again, it doesn't give any errors when executing any of the code. However, if I click to active the same code a second time, the re-parenting code throws a null warning as expect, and the childNEW is properly moved to the correct location. I thought about putting in a delay to run the movement code a fraction of a second later, but the player will still see the child in the wrong location for a split second and it'll look bad. How do I get around this wrinkle? Thanks again.

I did some additional debug checks and this visual quirk may be a bug. I inserted x/y position checks at each stage of the code and this is what I got:

  • 0/0 - it thinks this is childMOVE's initial position, it should return 600/-64
  • 663.5/0 - this is once childMOVE is re-parented, visually appears to be 0/0
  • 663.5/0 - this is once childNEW's variable is assigned
  • 600/-64 - this is once childNEW is re-positioned, but the TextureRect doesn't actually move

Visually, none of these coordinates seem correct.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.