z_index resets to 0

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

I have a parent Node called TileGrid which populates automatically with a bunch of child Nodes called Tile. To help me manage the children I have created a 2D Array called grid_tiles[][] which contains references to each child Node.

When _ready() runs on my TileGrid it first creates all the child Nodes, then it adds them each to the grid_tiles[][] array. Finally, it’s supposed to set the Z-Index for each Tile… but it doesn’t work! I rigged it so that when I hover the mouse over a Tile it prints the z_index to the console… and all of them read as 0.

So, with both of these taking place within TileGrid._ready(), this line does NOT work:

grid_tiles[x][y].node.z_index = new_z

… but this DOES work:

grid_tiles[x][y].node.modulate = Color(1,.5,.5,.5)

At no point am I receiving any errors.

If I rig my hover-over-tile code I can get it to modify the Z-Index… so I assume somewhere between TileGrid calling _ready and when I’m able to start using the mouse the Z-Indexes are getting reset back to 0.

Can anyone help me understand when and why the z_index values are getting reset, and at what point that is happening so I can move my code line somewhere where the Z-Index changes will actually stick?

Thanks in advance.

Can you post your node structure for the Tile object? Can you paste the setup code around grid_tiles[x][comment0-y].node.z_index = new_z and the code you are using to get the z_index when you hover?

Have you verified in the remote scene tree that the z_index value isn’t set properly?
Overview of debugging tools — Godot Engine (stable) documentation in English

timothybrentwood | 2021-05-18 23:13

The Nodes within Tile look like this:

  • Tile (Node2D)
  • Textures (Node2D)
    • Background (Sprite)
  • WireMesh (Node2D)
    • Area2D
      • CollisionPolygon2D
    • BorderLines (Node2D)

(… the linespacing looks really wrong in the list above, but not sure if its this Donut Theme or if my Markdown is wrong)

I have this code in TileGrid._ready():

for grid_y in grid_size_y:
	for grid_x in grid_size_x:
		hex_tile_node = hex_tile_scene.instance()
		hex_tile_node.grid_location.x = grid_x
		hex_tile_node.grid_location.y = grid_y
                    hex_tile_node.position.x = (grid_x * row_offset.x) + (grid_y * column_offset.x)
		hex_tile_node.position.y = (grid_x * row_offset.y) + (grid_y * column_offset.y)

for grid_x in grid_size_x:
	for grid_yy in grid_size_y:

for child in self.get_children():
	if child.is_in_group('TILES'):
		grid_tiles[child.grid_location.x][child.grid_location.y] = {'node': child, 'grid_x': child.grid_location.x, 'grid_y': child.grid_location.y, 'material': '_EMPTY'}

var new_z = 10000
for y in grid_size_y:
	for x in grid_size_x:
		grid_tiles[x][y].z_index = new_z
		grid_tiles[x][y].node.z_index = new_z
		new_z -= 1

I added a .update_z_index() function to Tile… but that doesn’t work either. It does, however, print the current .z_index for the selected Tile… and it is always 0.

Now, as for getting Z-Index to work with hover:
You’ll see that I have a CollisionPolygon2D inside the Tile objects; if I go to their _on_Area2D_mouse_entered() function and add:

z_index += 10

then when I put my mouse over the Tile lo; it pops up above all the other Tiles and I can see in the console (courtesy of print(z_index)) that the Z-Index has risen.

I don’t seem to be able to use the Remote Scene Tree to investigate, as there are no Tiles actually in the Scene until TileGrid._ready() executes and spawns them.

zachMade | 2021-05-19 00:10

I think this might be happening because your Tiles aren’t unique.

  • Navigate to your Tile scene in the editor and select the root node
    of the scene in the Scene panel.
  • Then go to the Inspector panel (default right side) and click the little screw driver/wrench button.
  • In the pop-up menu press the Make Sub-Resources Unique option.

Then try to re-run your game and see if that fixes it.

timothybrentwood | 2021-05-19 00:28

Nope, no dice :frowning:

zachMade | 2021-05-19 00:33

Is the _on_Area2D_mouse_entered() function connected to the Tile node’s script?

Just for kicks change:

grid_tiles[x][y].z_index = new_z


grid_tiles[x][y].set_deferred("z_index", new_z)

timothybrentwood | 2021-05-19 00:45

Yes, _on_Area2D_mouse_entered() is connected to the script for Tile.

Unfortunately, .set_deferred() didn’t work either.

zachMade | 2021-05-19 01:53

:bust_in_silhouette: Reply From: zachMade

Solved! By kleonc on Reddit:

Looking at the set_z_index source code it will fail for values greater than VS:CANVAS_ITEM_Z_MAX = 4096.

By assigning Z-Index values within the acceptable range (-4096 to 4096) it works as expected!

For future reference, this is being documented in the class reference: Document valid range of Node2D.z_index by kleonc · Pull Request #48867 · godotengine/godot · GitHub

Calinou | 2021-05-19 23:54