Can I specify Z-index for Tile in Tileset (Tilemap) ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Majesty
:warning: Old Version Published before Godot 3 was released.


I have a Tileset which contain many elements that should be drawn over the player Sprite. To do that, I changed the value of the Sprite of each Tile concerned, and when I use the converted Tileset.tres in a Tilemap, my player is still drawn after thoses tiles.

However, when I set the Z value of the Tilemap, I can correctly draw the entire layer on top of the player Sprite.
Does setting Z value for individual Tiles in Tileset is not supported, or am I doing something wrong ?

I’d appreciate any help!

:bust_in_silhouette: Reply From: eons

Not that I know of.
The best option may be to create a secondary TileMap for foreground objects (like one normally do with other engines/tilemap editors).

To be clear – since I couldn’t figure this out without some experimentation – the process is:

  • Create two tilesets (say ground and objects)
  • Create two layers: say one grass/ground and one trees/objects
  • Set the Z-index on the object layer to a higher value. Setting it on the tileset (eg. root `Node2D element), or on individual tiles, doesn’t do anything.

nightblade9 | 2018-07-29 02:30

I was just about to do that, but my sprites are all z-indexed by their Y position, so some will be behind a wall while others will be in front of the wall. This solution won’t work for that.

paul.holt | 2019-04-27 06:11

Here is what I ended up doing in my 2d top down for things like tree’s, where you are z-indexing by y like paul.holt above:

  • Update player object z-index by its y position at the end of its _PhysicsProcess method.
  • Use a TileMap for the ground under the player.
  • Make your “foreground objects” into Sprites (Things like trees for example)
  • Make a script that extends Sprite, and in _Ready update its z-index to its y position
  • Make your sprite a child scene and instantiate it on your main scene everywhere you want it

That works really well for me and my game, and is easy to implement.

LuminousSilver | 2020-03-01 09:03

:bust_in_silhouette: Reply From: ccpixel

Maybe it was not available yet when this question was first answered, but to be clear, you can change the z_index of individual tiles in an atlas or autotile. There is a tab for z_index on the same menu where you can select a region of tiles, set bitmasks, collisions, etc for a tilemap. You can set the bottom tiles of an object to have a different z_index for example.

However, if you are trying to have a player be able to go behind and in front of objects in top down 2D world, it may be better to go with a solution like LuminousSilver mentioned. I would recommend creating each object as a sprite and make all the sprites the child of some node. Add all the sprites to a group. Then you can attach a script to the parent node to call all the nodes in the group and set the z_index equal to their y position. For example, I put all my building sprites in the group “Buildings”. I add the following code:
To the player:

z_index = position.y

To the parent node of the building sprites:

func _ready():
	var nodes = get_tree().get_nodes_in_group("Buildings")
	for node in nodes:
		node.z_index = node.position.y