Issue when creating 3D buttons for each animation (2D GUI example included)

Hi! I’m trying to have 3D buttons created for each animation in an imported .glb and populate a 3D stackpanel with the 3D buttons.

Can someone please tell me why the following works for creating buttons for each animation in the .glb with a 2D GUI? (see lines 129-159)

See demo here: Babylon.js Playground (babylonjs.com)

var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("Header");
        advancedTexture.idealHeight = 1080;

var animBtnsPanel = new BABYLON.GUI.StackPanel("animBtns");
        animBtnsPanel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
        animBtnsPanel.width = "25%";
        advancedTexture.addControl(animBtnsPanel);
var currGroup;
        for (let group of result.animationGroups) {
        // Add a button for that group
        group.stop();

        var groupBtn = BABYLON.GUI.Button.CreateSimpleButton(group.name, group.name);
        groupBtn.width = 0.95;
        groupBtn.height = "80px";
        groupBtn.color = "white";
        groupBtn.fontSize = 20;
        groupBtn.cornerRadius = "10";
        groupBtn.background = "Grey";
        groupBtn.paddingBottom = 10;
        animBtnsPanel.addControl(groupBtn);

        groupBtn.onPointerClickObservable.add(() => {
            // Stop other playing animations
            for (let othergroup of result.animationGroups) {
                if (othergroup !== group) {
                    othergroup.stop();
                }
            }
            // Play the animation
            group.reset();
            group.play(true);
            currGroup = group;
        });   
        }

But this seemingly similar does not create buttons for each animation when using a 3D stackpanel and Button3d?

var manager2 = new BABYLON.GUI.GUI3DManager(scene);

var anchor4 = new BABYLON.TransformNode("anchor4");
    anchor4.position.x = -3;
    anchor4.position.y = 6.5;
    anchor4.position.z = -5;
    anchor4.rotation.x = 0;
    anchor4.rotation.y = 3.1416;
    anchor4.scaling = new BABYLON.Vector3(0.5, 0.5, 0.5);

var panel = new BABYLON.GUI.StackPanel3D(true);
    manager2.addControl(panel);
    panel.linkToTransformNode(anchor4);
var currGroup;
        for (let group of result.animationGroups) {
            // Add a button for that group
            group.stop();

            var groupBtn = new BABYLON.GUI.Button3D(group.name);
            groupBtn.content = group.name;
            panel.addControl(groupBtn);
            
            groupBtn.onPointerClickObservable.add(() => {
                // Stop other playing animations
                for (let othergroup of result.animationGroups) {
                    if (othergroup !== group) {
                        othergroup.stop();
                    }
                }
                // Play the animation
                group.reset();
                group.play(true);
                currGroup = group;
            }); 
        }

I’m trying to recreate the same type of GUI but in 3D space where I have placed 3D buttons around an object with animations.

The content of the Button3D needs to be a 2D control like here: https://playground.babylonjs.com/#EWIQ8X#1

1 Like

I’m starting to run out of compliments for the work you and the other moderators/super users are doing here. I can only dream of having even a fraction of the knowledge you people possess someday…

But thank you so very much for your help and time! It solved like a charm.

Just a quick follow up question. How do I set it so that also the last added button gets the correct margin? It seems as if the “panel.margin = -1;” is not applied (or is perhaps applied multiple times…) to the last button added.


var panel = new BABYLON.GUI.StackPanel3D(true);
    manager1.addControl(panel);
    panel.linkToTransformNode(anchor4);
    panel.margin = -1;


var currGroup;
        for (let group of result1.animationGroups) {
            
            // Add a button for that group
            group.stop();

            var groupBtn = new BABYLON.GUI.Button3D(group.name);
            var text3D = new BABYLON.GUI.TextBlock();
            text3D.text = group.name;
            text3D.color = "white";
            text3D.fontSize = 24;
            text3D.scaleY = 2.6;
            text3D.scaleX = 0.6;
            groupBtn.content = text3D;
            panel.addControl(groupBtn);
            
            groupBtn.scaling = new BABYLON.Vector3(2, 0.4, 1);
                      
            groupBtn.onPointerClickObservable.add(() => {
                // Stop other playing animations
                for (let othergroup of result1.animationGroups) {
                    if (othergroup !== group) {
                        othergroup.stop();
                    }
                }
                // Play the animation
                group.reset();
                group.play(true);
                currGroup = group;
                slider.isVisible = true;
                playBtn.isVisible = true;
                pauseBtn.isVisible = true;
            }); 
        }  

Edit: If I remove the “panel.margin = -1;” the last added button still gets a lot more margin added compared to the rest. And the imported buttons are ordered from bottom to top instead of top to bottom.

Could you post a PG for your 3D GUI?
There might be an issue with the loop, where instructions are added twice or not at all because the control is not yet added to the panel.

It seems that putting “panel.blockLayout = true;” before and “panel.blockLayout = false;” after the loop solved it!

So it seems it is all sorted atm. Thanks again!

1 Like

Good. I’m happy to hear that. It’s actually explained in the doc and is a bit different from the 2D GUI. Point is you can only layout your controls after they have been added to the manager/panel.

By default, all containers will update their layout everytime you add a new control to it. But you can optimize this behavior if you plan to add multiple controls in a row with container.blockLayout = true

It’s good you found the solution on your own. GJ and have a great day :sunglasses:

2 Likes