GUI SimpleButton overlapping issue

Hi folks,

Having a bit of a strange issue with GUI SimpleButtons. I’m trying to find a way to have them display so that they’re layered. I’m using zIndex to set the rendering position because that seems to be how you would handle it properly according to other forum posts.

Here’s a demo: https://boehringer-stage.pilotio.workers.dev the yellow button should appear on top of the white button.

Here’s the method I’m using to generate it:

  private createHubPopup(target: AbstractMesh, title: string, button: string, link: string) {
    const plane = MeshBuilder.CreatePlane(
      'HUB_LABEL',
      {
        width: 120,
        height: 120,
        sideOrientation: Mesh.DOUBLESIDE
      }
    );
    const pos = target.position;
    plane.position.y = 50;
    plane.position.x = pos.x;
    plane.position.z = pos.z;
    const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane);
    const popup = Button.CreateSimpleButton("BUTTON_1", title);
    popup.color = "black";
    popup.cornerRadius = 50;
    popup.fixedRatio = 0.15;
    popup.fontFamily = "Interstate";
    popup.shadowColor = '#ccc';
    popup.shadowBlur = 10;
    popup.fontSize = 47.5;
    popup.fontWeight = "normal";
    popup.thickness = 0;
    popup.zIndex = 0;
    popup.background = "white";
    popup.onPointerUpObservable.add(() => {
      window.location.href = link;
    });
    const plane2 = MeshBuilder.CreatePlane(
      'HUB_LABEL_SECOND',
      {
        width: 50,
        height: 50,
        sideOrientation: Mesh.DOUBLESIDE
      }
    );
    plane2.position.y = 40;
    plane2.position.z = pos.z - 8;
    plane2.position.x = pos.x;
    const advancedTexture2 = AdvancedDynamicTexture.CreateForMesh(plane2);
    const popup2 = Button.CreateSimpleButton("BUTTON_2", button);
    popup2.color = "white";
    popup2.cornerRadius = 50;
    popup2.fixedRatio = 0.15;
    popup2.fontFamily = "Interstate";
    popup2.fontSize = 60;
    popup2.thickness = 0;
    popup2.zIndex = 50;
    popup2.fontWeight = "normal";
    popup2.background = "#ffc800";
    popup2.onPointerUpObservable.add(() => {
      window.location.href = link;
    });
    advancedTexture.addControl(popup);
    advancedTexture2.addControl(popup2);
    plane.lookAt(new Vector3(0, 50, 0), 3.14);
    plane2.lookAt(new Vector3(0, 50, 0), 3.14);
  }

On other strange detail. I’m adding a shadow blur which looks great but the very right and left sides get cut off. I suppose it’s a matter of just resizing and positioning the button inside the plane?

Thanks!

Hello!
I’m not sure what’s the problem from the code snippet that you’ve provided, but if you change the z position of the planes does it make any difference? Did you try it with the full screen ADT? A Playground example would be very useful without any extra code. This way you can be sure that the problem is not in your code and we can help you to analyze it. :vulcan_salute:
R.

EDIT: I’ve visited some of your other posts and didn’t know that you are such familiar with BJS, so ignore my two last sentences please, you already know that :slight_smile:

I use the simple buttons in my project and I can z-order them as I wish, but I’m using the full screen ADT so in this mode it should work :slight_smile:
image

@roland thanks! But I wouldn’t say I’m totally familiar but yeah I’m 2-3 projects deep with BJS. For some reason my clients tend to come back to me for 3D contracts every so often. I’ve done about 10 projects with ThreeJS as well shrugs.

I did set zIndex of the popup and also set the z to ensure the element is closer to the camera:

plane2.position.z = pos.z - 8;

What I’m starting to realize is that I’m using lookAt() for each item separately. Since one is smaller than the other the rotation is slightly different ie. the yellow button and white button are articulated differently.

I suppose if I just set the rotation of the yellow to the main element this might resolve the issue. Sigh.

But the question still stands, is there a way in BJS to force an element to render on top of the other no matter what? I’m not sure if there are viable use cases for it, it’s just a curiosity at this point.

Hmmm I just tried adjusting the rotations so they are the same articulation:

plane.lookAt(new Vector3(0, 50, 0), 3.14);
plane2.rotation = plane.rotation;

No difference. There’s some strange rendering things here I’m totally unsure about. If you walk slightly in front you see the yellow button is in front.

If you rotate so the camera is behind then you get this:

I was hoping I didn’t have to drop this into a repro but here we go :slight_smile: sorry I should have done it from the start: https://playground.babylonjs.com/#DT7AQC#19

Sorry about the camera movement, I didn’t use the same camera controls to simplify the repro.

This is what you are trying to achieve?

1 Like

I had the same problem before, I was developing locally but had to create a repo for the good souls around here to have a look at my issues. Now I am creating my methods separatelly, one method = one job (I think, it is generally a good idea to code this way though) so it is very easy to put it in a PG.

Ok, it is behaving a bit weird. I have created a short video for the BJS guys:
https://babylonjs.nascor.tech/v.mkv
Will you please post a link to this topic into the Bugs section?

However here is a working version, just set the renderingGroupId, lines 45 and 74, to force the rendering order:
https://playground.babylonjs.com/#DT7AQC#23

EDIT: if you don’t want to reveal your code, strip it to the bare minimum as I did with your PG :sunglasses::+1:

Ahhhhhaaaa. Thanks for the fix. I will post in the Bugs section, no worries.

So the thing is that I really don’t like the way BJS sets up it’s structure by default. I’m very much a modern JS coder. I use TS, Vite or Snowpack for my bundling and I love code-splitting and quality source optimization. My environment and setup is very atypical for what I’d imagine other BJS users would use.

For this reason my setup is really different than the standard BJS setup. Hell I even hate how everything is prefixed with “BABYLON”. I actually use the modern import style and I end up creating ESM exports for inclusion in other parts of my projects. This helps my team digest the more complex tooling I build by importing classes and instantiating it as needed.

This is a really long way of saying, recreating a full Playground friendly BJS repro of my work is painnnnfullll. This is probably my largest complaint about BJS. If it was less prescriptive or if the Playground had an easier way that I can copy and paste

This isn’t a slight yo BJS, it’s just a different working style. I do secretly wish it could be more modern and in-tune with the rest of the modern JS world though. Three’s packaging and tooling ecosystem seems to be ahead as a result. Then again BJS comes with sooo many goodies and niceties.

Thanks for your help @roland. I still don’t understand what the behaviour is here but I’ll track the bug and try to understand what the issue is.

Oh shoot, last thing. This is dumb but my shadow is being clipped here. Would I just resize my button before applying it to the plane. I found it difficult to understand the SimpleButton and how it maps to the plane so like the sizing ended up being very trial + error. I didn’t bother messing with it more but maybe you have a quick suggeestion:

Same here, I’m using Quasar/Vue/Webpack/TS/ES6 imports for all my projects, but I’m a big fan of functional programming so all my methods can be easily isolated and transferred elsewhere. Yes, the BABYLON namespace must be added manually when copying the code from an ES6 project to the PG, but ces’t la vie :smiley: Maybe it’s time to write a simple transpiler.

You are welcome, glad to help dude! :slight_smile:

One thing I have noticed is that the position vector3 is changing very weirdly. Look how far are the two planes and the z value is only -0.09.

At your service! :smiley:

Ah shit lol another deceptively simple solution to that padding issue. I mean I DID see those values but my headspace was about sizing the element inside the plane as opposed to padding it. Sigh, with enough trial and error I would have likely gotten it but you saved me a bit of time.

Thanks so much. Also about that positioning, hmmm that’s interesting. TBH I wonder if that’s related to something else I have to investigate. The mainland has a couple meshes labeled as markers which I use to position these popup things. In some cases the position of the marker that renders is off from where the popup is placed.

I haven’t bothered asking about it because I suspect it’s just me being silly but now that you mention a positioning issue I’m wondering if there’s something strange/deeper happening that’s throwing a few things off.

Don’t mention it dude! Live long and prosper! :vulcan_salute:

1 Like

Regarding your further investigation I would wait for a response from the BJS team.

Yeah I think I’ll do that. HEY do you know of any good sources or documentation that can explain collision mask and group? I’m starting to realize that I need to implement different actions for different mesh collissions.

You can only capture clicks on one adt and I’m pretty sure I see you doing two. It says that somewhere in the documents. You can manually fire the click events though.

Let me see if later I can find the code for how to do the work around.

The correct thing to do would be to make one adt, with two containers and use the containers like your using the two adts.

I’ve found the required information in the docs and/or by doing a PG search in all the cases yet.

@msDestiny14 might be able to help with the GUI part here.

1 Like