Make GUI plane only pickable where Controls are placed (click through whitespace)


To increase performance I use a single plane for multiple GUI controls.
On this GUI plane there is some whitespace where no controls are placed.
When I want to click a GUI element that is behind this bigger GUI, the events are blocked by the whitespace of the GUI.

This is the GUI I want to create:

The red box is the plane where I placed the GUI on:

This playground show an example. You cannot click the back buttons when you click between the front buttons:

Is there a solution for that or should I create a plane for every single UI element?

Thank you!

Pinging @msDestiny14

Is it possible to archive a similar behavior to the FullscreenUI? When using the fullscreen UI only the Controls are pickable and not the whole screen.

1 Like

Let me take a look. :slight_smile:

Hi there! I agree with @marlon360 a fullscreen UI would help because then you can just layout controls onto of controls. However that may not get the depth you want.

I tried a bunch of different solutions but didn’t yield the result we wanted. I tried:
firstPlane.isPickable = false;
button.isHitTestVisible = true;

The problem is we want the mesh to not be active but the Gui to still be clickable.

This is a very naive approach, but you could play with mesh picking in that case - GUI blocking other GUI | Babylon.js Playground

Those events are anyhow being triggered, so there is no performance hit


You can sample from the ADT texture and discard hits on transparent pixels by adding this to the end of your intersects method on the related mesh (pi: PickingInfo, advancedTexture: AdvancedDynamicTexture)

      if (pi.hit && pi.getTextureCoordinates()) {
        const { x, y } = pi.getTextureCoordinates()!;
        const { width, height } = advancedTexture.getSize();
        const sx = Math.round(x * width);
        const sy = Math.round(height - y * height);
        const point = advancedTexture.getContext().getImageData(sx, sy, 1, 1);
        // if the texture pixel under the picked point is transparent, ignore the hit
        if ([3] < 0.5) {
          pi.hit = false;
          pi.pickedPoint = null;
          pi.pickedMesh = null;
1 Like