Image Element input z order

I have a bunch of Image Elements in the scene (3D UI), they are all set to the World Layer for correct Z ordering. The thing that behaves (in my opinion) wrong is the input and which Element is currently hovered. It seems that the Engine picks the top Element in the Hierarchy if two or more Elements are currently on top of each other and picks that one as one being hovered.

By hovered I mean this.entity.element.on('mouseenter', this.onMouseEnter, this);


As you can see on this image, the Element #1 is being highlighted (the onMouseEnter is called), but in fact the user is currently hovering Element #2. If I switch the Element #1 to be below Element #2 in the scene hierarchy, the hovering works correctly. The same can be said if I rotate the camera 180°.

What comes to mind is tracking all Element’s distance from camera and sorting them every frame?

Thanks for any tips!

I don’t believe that the UI events are based on the sorting/rendering order and would be via the hierarchy order.

I would have some logic that keeps track of all the elements have been mouse entered, then run some logic to work out which one is closest to the camera and perform the hover logic on that element.

Well the thing is that only one element is being set as hovered at a time - when the mouse cursor hovers onto the bottom one (#1), the this.entity.element.on('mouseleave', this.onMouseLeave, this); is being called (lol forgot to mention this :man_facepalming:) on the top one (#1).

Ah, :thinking: I don’t have an answer off hand and sounds like a bug now.

The way that I would work around it for now is to manual set the order based on the distance from the camera.

Have all the UI elements for this on a new layer with the sorting order set to None or Manual (not sure which one it should be off hand) and have some logic each frame that sets the drawOrder based on the distance from the camera.

Yeah that’s what I was thinking too. I will try to manually order it myself, but I think the manual drawOrder wouldn’t matter as the element itself is drawn correctly (on top of each other the correct way).

I guess there is some kind of line trace being done every frame to check whether the element is being hovered? Not sure, did not look that deep into the engine, but if so, maybe the line trace works on a different layer (UI) than what is being set for the element in the editor (World)?

It’s done on a box check basically and done based on the drawOrder property.

Looking at the code, the element check order is based on the drawOrder. My guess here is that since it currently based on the depth order, drawOrder is not updated on the element during the engine update.

Setting it manually should get around this.

1 Like

Having trouble replicating this issue in this project:

Is there anything you are doing that is different?

Well that is interesting, as I have the same issue in your project. Or did you manage to replicate it? I will try another browser. Currently running on Win10 Chrome ver. 92.0.4515.159.

Edit: Same on Edge ver. 92.0.902.78
Edit2: I just tried to put all elements into their own new layer (Manual order) and set their drawOrder based on distance to the camera, the elements are rendered correctly on top of each other, but the mouse event still behaves the same as before.

Oh, how weird. Haven’t changed anything and now I get it

Ticket created: UI elements events on the world layer are triggered in the 'wrong' order · Issue #3427 · playcanvas/engine · GitHub

1 Like