How to add unknown number of Items to a StackPanel made in the GUI editor?

I created a character selection screen with the online GUI editor, but am not sure how to programmatically add each characters’ panel. I am able to do it no problem with the Babylon GUI through code. The number of characters will vary per player, so I can’t manually create each panel. How do I create a unique instance of each character Panel and add it to a Stack Panel?

Thanks!

FWIW, I made some progress by making each Character Panel it’s own snippet. I then created a new AdvancedDynamicTexture.CreateFullscreenUI(“GUI”) at the start of every loop(going through all the characters data). I am able to see the different character data, but they don’t seem to fit properly into the first GUI’s stack panel.

Hi @martymav and welcome to the forum

Can you please try to do a small repro in the playground? It will help us a lot trying to figure out the issue.

Mostly works, but for some reason I have to resize the window. But then it displays the Items twice. Also stackPanel._children and charNameText.text tell me they do not exist on type ‘Control’, even though they both work. I feel I am overlooking something simple.

I think @DarraghBurke knows more about GUI than I do :slight_smile:

Hi! There’s a few different questions here, I’ll try to answer each one

  1. getControlByName() returns objects of type Control. StackPanel extends Control and has a children property, and TextBlock extends Control and has a text property, but the parent class doesn’t have either. If your playground uses TypeScript, you can write getControlByName() as StackPanel to tell the type system that you’re actually looking at a StackPanel. Unfortunately, we don’t have a way to do this in JavaScript; all types are inferred in JS. So, feel free to use those properties, but the intellisense will unfortunately not be able to suggest them.
  2. The way I would recommend handling this is to put a single “template” child inside the stack panel in your GUI. You can clone it by serializing it into a string, and then creating new controls which are parsed from that string. (Unfortunately we don’t yet have an easy way to directly clone controls.) Then, you can hide it with isVisible = false or by deleting it.
  3. In order to get children of the newly cloned controls, you’ll want to use getDescendants() rather than getControlByName, because you’re only interested in controls descending from that particular one. I used a filter where we check the control’s name to be sure we’re getting the right one, and then I just grab the first returned element since that function returns an array.

Here’s a PG putting it all together: rendering multiple children to stack panel | Babylon.js Playground (babylonjs.com)

Hope this is helpful! Love that you’re using the GUI editor :slight_smile:

3 Likes

Works like a charm, thank you! I’m new to the Babylon ecosystem, as I have mostly worked with Unity. But the way you explained it makes perfect sense, I’m just still new to the intricacies of Babylon :slight_smile:

1 Like

Happy to help and so glad to have you here!

Hi guys, just wanted to add to this.

I implimented it as @DarraghBurke lined out and it did work BUT! the outputted component I wanted “characterItemGUI” came out small.

Instead of working around it, another way I got around this was finding the comp I wanted from the outputted BabylonGUI json file and made it into its own file and just used Rectangle.Parse() on that single component .json file and it worked a treat and has the nice bonus of being segmented from the master UI.

I don’t see a way to contribute to gui.babylonjs right now, but a feature I would love is the ability to output a single item or group as a .json file (think Snippits or Frames in deisgn programs like Sketch and Figma) and then just parse those smaller json snippits and not treat it as a fullscreen ui!

cc @carolhmj

Created an issue to track the ask: [GE] Save and load a single Control and its children as a JSON · Issue #13132 · BabylonJS/Babylon.js (github.com)

1 Like