+1 vote

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.

Godot version 3.3.stable.official
in Engine by (20 points)

Can you post your node structure for the Tile object? Can you paste the setup code around grid_tiles[x][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?

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.

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.

Nope, no dice :(

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)

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

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

1 Answer

0 votes
Best answer

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!

by (20 points)

For future reference, this is being documented in the class reference: https://github.com/godotengine/godot/pull/48867

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.