Build a Shared Score Panel in Banter
Banter public space properties hold shared values for a space. Combine SetPublicSpaceProps() with space-state-changed and the Banter UI system to show a score that responds to state updates.
Create a world-space UI panel, add a label and button, then connect the controls to a public space property.
- Create a
BanterUIPaneland add a score label. - Write score changes with
SetPublicSpaceProps(). - Update the label from
space-state-changed.
Create the World-Space Panel
BanterUIPanel must first be added to a GameObject. Set screenSpace to false for a panel placed in the scene:
const panelObject = new BS.GameObject({
name: "SharedScorePanel",
localPosition: new BS.Vector3(0, 2, 3)
});
const panel = panelObject.AddComponent(
new BS.BanterUIPanel({
resolution: new BS.Vector2(800, 600),
screenSpace: false,
enableHaptics: true,
clickHaptic: new BS.Vector2(0.1, 0.05),
enterHaptic: new BS.Vector2(0.05, 0.02),
exitHaptic: new BS.Vector2(0.05, 0.02),
enableSounds: false
})
);
The haptic vectors contain amplitude and duration values in the official component example.
Add the Score Label
Create a UILabel, set its text and style, then append it to the panel root:
const scoreLabel = new BS.UILabel();
scoreLabel.SetProperty(BS.PN.text, "Score: 0");
scoreLabel.style.fontSize = "36px";
scoreLabel.style.color = "#FFFFFF";
panel.root.AppendChild(scoreLabel);
Keep the scoreLabel reference so the state event can change its text.
Add an Increment Button
let score = 0;
const addButton = new BS.UIButton();
addButton.SetProperty(BS.PN.text, "Add Point");
addButton.style.width = "200px";
addButton.style.height = "50px";
addButton.style.backgroundColor = "#4CAF50";
addButton.style.color = "#FFFFFF";
addButton.OnClick(() => {
scene.SetPublicSpaceProps({
gameScore: String(score + 1)
});
});
panel.root.AppendChild(addButton);
The official state example stores values such as gameScore as strings.
Listen for Shared Score Changes
space-state-changed supplies a changes collection. Each change includes the property name, old value, and new value:
scene.On("space-state-changed", (event) => {
for (const change of event.detail.changes) {
if (change.property !== "gameScore") {
continue;
}
score = Number(change.newValue) || 0;
scoreLabel.SetProperty(
BS.PN.text,
`Score: ${score}`
);
}
});
Filter by property name before updating the display because the event may report changes to other public space properties.
Send an Event Instead of Storing State
For an action that does not need to remain as the current score, Banter also provides one-shot messages:
scene.OneShot({
type: "score-effect",
data: { value: score }
}, true);
Use a public space property for the current score and a one-shot message for a discrete action that listeners handle as an event.
Common Questions
Why does my Banter score label never change?
Confirm that the listener checks the same property name passed to SetPublicSpaceProps(). In this example, both use gameScore.
Should the score use a public property or a one-shot message?
Use the public property for the value that represents the current score. Use a one-shot message for a separate event that does not need to remain as stored state.
Official References
Related Navigation
- Banter Multiplayer State and Events
- Banter In-World UI System
- Banter SDK Enums and Constants
- Banter VR Documentation