Hi, i’m very new to PlayCanvas and i was wondering if there’s a comprehensive guide on how to build a user interface in the editor. I’ve been looking around but it’sa like putting together a puzzle from different puzzle sets
thanks in advance
Hi, i’m very new to PlayCanvas and i was wondering if there’s a comprehensive guide on how to build a user interface in the editor. I’ve been looking around but it’sa like putting together a puzzle from different puzzle sets
thanks in advance
A user interface that does what?
It needs to be dynamically generated, what i’m trying to achieve is to write a script that will allow on the inspector to add elements to the UI (in this case panels and buttons) according to the needs at hand
Wait, you mean not in a project but adding more buttons to the editor? I dont know if thats even possible.
no no, i mean in the project, her’s the flow i have in. mind:
var DynamicUi = pc.createScript('dynamicUi');
DynamicUi.attributes.add('panelCount', {
type: 'number',
default: 2,
description: 'Number of panels to create (default is 2)'
});
DynamicUi.attributes.add('buttons', {
type: 'json',
array: true,
schema: [{
name: 'panelIndex',
type: 'number',
default: 0,
description: 'Panel index to which this button belongs'
}, {
name: 'label',
type: 'string',
default: 'Button',
description: 'Label of the button'
}, {
name: 'image',
type: 'asset',
description: 'Image for the button'
}, {
name: 'backgroundColor',
type: 'rgb',
default: [1, 1, 1],
description: 'Background color of the button'
}, {
name: 'action',
type: 'string',
enum: [
{ "none": "none" },
{ "customAction": "customAction" }
],
description: 'Action to perform when button is clicked'
}]
});
// initialize code called once per entity
DynamicUi.prototype.initialize = function() {
this.panels = [];
for (let i = 0; i < this.panelCount; i++) {
let panel = new pc.Entity('Panel' + i);
console.log('Creating panel: ' + panel.name);
panel.addComponent('element', {
type: 'group',
width: 330,
height:440,
color: new pc.Color(0, 1, 0, 0.3)
});
this.setPanelPosition(panel, i);
this.entity.addChild(panel);
console.log(`added ${panel.name} to ${this.entity.name}`)
this.panels.push(panel);
let foundPanel = this.entity.findByName(panel.name);
if (foundPanel) {
console.log(`Confirmed panel ${panel.name} is present as a child of ${this.entity.name}`);
} else {
console.error(`Panel ${panel.name} was NOT found after adding.`);
}
}
console.log("Panels created, now creating buttons...");
this.buttons.forEach((buttonData) => {
if (buttonData.panelIndex < this.panels.length) {
this.createButton(buttonData, this.panels[buttonData.panelIndex]);
console.log(`Button created for panel index: ${buttonData.panelIndex}`);
}
});
console.log("Finished creating buttons, adding resize listener...");
this.app.graphicsDevice.on('resizecanvas', this.onResizeCanvas, this);
};
DynamicUi.prototype.setPanelPosition = function(panel, index) {
let width = window.innerWidth;
console.log('Index',index)
if (width < 768) {
panel.element.anchor = [0, index * 0.5, 1, (index + 1) * 0.5];
} else {
panel.element.anchor = [index * 0.5, 0, (index + 1) * 0.5, 1]
}
};
DynamicUi.prototype.onResizeCanvas = function() {
console.log('Canvas resized');
// Reposition panels if needed
for (let i = 0; i < this.panels.length; i++) {
this.setPanelPosition(this.panels[i], i);
}
};
DynamicUi.prototype.createButton = function(buttonData, panel) {
let button = new pc.Entity('Button' + buttonData.label);
button.addComponent('element', {
type: 'button',
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5],
width: 100,
height: 40,
color: buttonData.backgroundColor,
text: buttonData.label,
useInput: true
});
button.addComponent('button', {
active: true
});
/*if (buttonData.image) {
button.element,textureAsset = buttonData.image
};*/
button.button.on('click', function() {
this.executeAction(buttonData.action)
}, this);
panel.addChild(button)
console.log('Button created: ' + button.name + ' in panel: ' + panel.name);
};
DynamicUi.prototype.executeAction = function(action) {
switch(action) {
case 'customAction' :
console.log('executing custom action');
break;
default:
console.log('button clicked')
}
}
// update code called every frame
DynamicUi.prototype.update = function(dt) {
};
Personally I would just have a bunch of premade panels then enable or disable them when needed.