What's the best way to setup restrictive on-boarding?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lordbry

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.

:bust_in_silhouette: Reply From: njamster

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)

Thanks for the guidance. I did this and it half worked. Progress! :slight_smile: 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.

lordbry | 2020-04-13 17:00

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.

lordbry | 2020-04-13 18:24