Issues with z_index handling for furniture in my game (perspective issues)

Godot Version

Godot 4.3

Hi everyone,

I’m currently working on a project in Godot where I need to adjust the z_index of furniture objects (like tables and chairs) based on the player’s position. The goal is to make sure that furniture elements appear in front or behind the player depending on the player’s vertical position (y axis). However, I’m encountering some issues when objects are not aligned along the same y axis, leading to perspective issues in the game.

Problem Description

I have a set of furniture objects in my scene, and I need to dynamically update the z_index of these objects (tables, chairs, etc.) relative to the player’s position. When the player is above a piece of furniture, it should appear behind, and when the player is below it, the furniture should appear in front.

The current setup

Player is represented by an AnimatedSprite2D and several CollisionShape2D nodes for different directions (front, back, left, right).
Furniture1 and Furniture2 are groups of objects that contain tables and chairs. Each table and chair is a child node with its own Sprite2D and CollisionShape2D.
Bar is a parent node that contains both Furniture1 and Furniture2, along with a TileMap.

The issue

When I place furniture1 and furniture2 at different vertical positions (different y values) in the scene, the z_index for furniture isn’t updating as expected.
The player should be in front of the furniture if their y position is lower, and behind if their y position is higher.
However, the z_index stays stuck or doesn’t adjust properly when moving between the different positions (e.g., between the lower y of one furniture and the higher y of another).

What I’ve tried

I’ve implemented a function that iterates through all furniture objects, compares their y positions with the player’s y, and adjusts their z_index accordingly. However, I still experience issues with the order of z_index not working as expected.

Here’s the code I’m currently using:

func update_z_index():
# Retrieve all furniture nodes in the “furniture” group
var furniture_nodes = get_tree().get_nodes_in_group(“furniture”)

z_index = 2  # Default z_index for the player (in front of the furniture)

# Loop through each furniture item in the furniture_nodes group
for furniture in furniture_nodes:
    print("Player Position Y: ", position.y, " Furniture Position Y: ", furniture.position.y)

    # If the player is in front of the furniture (player's Y position is less than furniture's Y position)
    if position.y < furniture.position.y:
        # Set the z_index of the player to be just in front of the furniture
        z_index = min(z_index, furniture.z_index + 1)
    else:
        # If the player is behind the furniture (player's Y position is greater than furniture's Y position)
        # Set the z_index of the player to be just behind the furniture
        z_index = max(z_index, furniture.z_index - 1)

What I need help with

Why is the z_index not updating properly when the player moves between different y positions for different pieces of furniture?
How can I properly adjust the z_index of the furniture (tables, chairs) based on the player’s position along the y axis?

Any advice or suggestions would be greatly appreciated!

Hi.
Isn’t that the purpose of this property of CanvasItem (node2d extend from it)

bool y_sort_enabled = false

void set_y_sort_enabled(value: bool)

bool is_y_sort_enabled()

If true, this and child CanvasItem nodes with a higher Y position are rendered in front of nodes with a lower Y position. If false, this and child CanvasItem nodes are rendered normally in scene tree order.

With Y-sorting enabled on a parent node (‘A’) but disabled on a child node (‘B’), the child node (‘B’) is sorted but its children (‘C1’, ‘C2’, etc) render together on the same Y position as the child node (‘B’). This allows you to organize the render order of a scene without changing the scene tree.

Nodes sort relative to each other only if they are on the same z_index.

I tried adding y sort enabled to my node 2D furniture 1 and also furniture 2 but it didn’t change anything. I don’t know if I need to add y sort enabled elsewhere or if I need to add script to make it work.

I’m adding the hierarchy of my project if that helps…

MainScene :
CanvasLayer
AudioStreamPlayer
Calling Player node with a camera 2D node
Calling Bar node

Player:
AnimatedSprite2D
CollisionShape2D_front
CollisionShape2D_back
CollisionShape2D_left
CollisionShape2D_right

Furniture1 :
2D node “Tables”
Sprite2D
StaticBody2D
CollisionShape2D

2D node Chairs
Sprite2D
StaticBody2D
CollisionShape2D

Furniture2 :
2D Node Tables
Sprite2D
StaticBody2D
CollisionShape2D

2D node Chairs
Sprite2D
StaticBody2D
CollisionShape2D
Sprite2D2
StaticBody2D2
CollisionShape2D

Bar:
Calling furniture1 node
Calling furniture2 node
TileMap node