Open KoBeWi opened 2 months ago
https://github.com/user-attachments/assets/5773156e-370b-483c-9304-4b540ff1de85
I think this should fix it for single clicking. I didn't look into group selections or anything like that, but I'm not sure that's relevant with z-index issues.
2D selecting ignores
z_index
It ignores rendering order in general. So all properties like show_behind_parent
, top_level
, y_sort_enabled
are not taken into account as well. Same about containing canvas layers.
For all of them it's as trivial to create an example of "wrong selection" as for z_index
.
Also note that z_index
is considered separately for each rendering canvas; meaning a canvas item with greater z_index
can still be drawn behind a canvas item with lower z_index
(if they belong to different canvases, e.g. different CanvasLayer nodes).
Well my original problem was with TileMapLayer. I have a foreground layer and background layer and the back layer was being selected over the front one. It's rather annoying.
I looked into this and found it more complex than anticipated.
As covered, we have to look at several different attributes. Since I figured the RenderingServer
was already doing all this, I looked there. The problem is, RenderingServer
is all about setting information, not retrieving it. You canvas_item_set_z_index()
and canvas_item_set_sort_children_by_y()
, but you don't retrieve these values. It's one way, at least for the majority of canvas_item
functions
For my PC, the RenderingServer
seemed to be RendererCanvasCull
which calls _render_canvas_item_tree()
which recursively calls _cull_canvas_item()
which in turn uses _attach_canvas_item_for_draw()
to add each CanvasItem
to a list ready to be rendered.
The order in which they are added to the list (z_list
) seems to be what determines the order that they're rendered in. The problem is that I don't know how to access this order. RenderingServer
doesn't seem to have an API to access it.
Likewise, I don't know of any API that can, for instance, tell if one CanvasItem is in front of another. To see if I could find one, I did a search of draw_behind_parent
but mostly only found the sections of code I've mentioned above.
So either we find a way to crack open the RenderingServer
, or we recode all the functionality in a separate function, maybe one that sorts a small list of CanvasItems
There was a short discussion here about a bandaid solution:
https://github.com/godotengine/godot/pull/96584#issuecomment-2332307061
I'll try to double check tomorrow to see if the RenderingServer
exposes any information regarding the absolute z order.
Besides the Godot editor, I imagine there are other usecases for knowing the renderered z order.
To me an API of some sort would make sense. Any issue with having the RenderingServer
set a field in each node containing the proper sort order as rendered?
Some potential solutions
RenderingServer
edits the CanvasItem
to include their absolute z order. Feel unsure about this because it does it in secretRenderingServer
API to include canvas_item_sort_absolute_z
that takes a list of CanvasItem
and sorts them front to back.RenderingServer
API to include canvas_item_get_frontmost
that takes a list of CanvasItem
and returns the CanvasItem
that's in front of all the others on that list.I could potentially code up any of the above solutions, but since we're dealing with API that's used by more than one class and appears in documentation, I'd want some backup on which option to go for.
Tested versions
4.3 4.2.2
System information
Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1060 (NVIDIA; 31.0.15.4633) - Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz (8 Threads)
Issue description
If lower node z-index wise is lower in tree, it will be selected through the top node:
https://github.com/user-attachments/assets/8e5ee496-b003-4588-b08f-1547a3bc247d
Steps to reproduce
Minimal reproduction project (MRP)
N/A