Player Specific Custom UI - bindings
Hi Creators,
I am trying to do player specific UIs with bindings. I'm following this but I think I'm not understanding it correctly. https://developers.meta.com/horizon-worlds/learn/documentation/desktop-editor/custom-ui/playerspecific-custom-ui
My goal is each user has health. If they collect a heart they will gain +1 health and display it on their custom UI. When I am testing with my teammate. We both start of as 0 (I know, 0 doesn't make sense for health, but for testing purposes let's start at 0 π) If bindings isn't the way to go, what could I do? If it should be bindings, does anyone know what I'm doing wrong? Example below.
When I collect 2 hearts, my UI will say 2, teammate will say 0. So far so good β€οΈ
Now my teammate collects 1 heart, my UI will say 2, teammate will say 3, NOT good π teammate should say 1
If I collect 1 heart, my UI will say 4, teammate will say 3. At this point the count is off for everyone. π
It seems like it's adding on based the last value.
Here is my code below. The first script is the trigger attached to a trigger for the heart
import { Component, CodeBlockEvents,Player, PropTypes} from 'horizon/core';
import { collectHealth } from 'HeadsUpDisplay';
class CollectibleItems extends Component<typeof CollectibleItems> {
static propsDefinition = {
numberToUpgrade: {type: PropTypes.Number, default:1.0},
};
start() {
this.connectCodeBlockEvent(this.entity, CodeBlockEvents.OnPlayerEnterTrigger,(player:Player)=>{
this.playerEnterTrigger(player);
})
}
playerEnterTrigger(player:Player)
{
this.sendLocalBroadcastEvent(
collectHealth,
{health: this.props.numberToUpgrade, player: player}
);
}
}
Component.register(CollectibleItems);Next is my custom UI that displays the health - which appears to work perfectly for one player. Multiplayer goes wonky. So I probably am misunderstanding how binding works
import { CodeBlockEvents, Color, Component, Player, PropTypes, TextureAsset, LocalEvent } from 'horizon/core';
import {
UIComponent,
View,
Text,
Binding,
UINode,
} from "horizon/ui";
export const collectHealth = new LocalEvent<{health: number, player:Player}>('collectHealth');
class HeadsUpDisplay extends UIComponent<typeof HeadsUpDisplay> {
static propsDefinition = {
maxHealthNumber: {type: PropTypes.Number},
};
private healthCount = 0;
initializeUI(): UINode {
const healthTitle = View({
children: [
Text({
text: this.strPlayerHealthTotal,
style: {
fontSize: 24,
fontFamily: 'Optimistic',
color: 'white',
},
}),],
style: {
flexDirection: 'row',
},
});
return View({
children: [healthTitle
],
style: {
},
})
}
start() {
this.connectLocalBroadcastEvent(collectHealth,(data:{health:number,player:Player})=> {
this.handleHealthUpdate(data.health, data.player);
})
}
strPlayerHealthTotal = new Binding<string>("0");
private handleHealthUpdate(health: number, player: Player): void {
this.healthCount++;
console.log("total health" + this.healthCount, ", player:" + player.name.get());
this.strPlayerHealthTotal.set(this.healthCount.toString(),[player]);
}
}
UIComponent.register(HeadsUpDisplay);
So combining the responses from above and this tutorial https://communityforums.atmeta.com/t5/Community-Resources/Mobile-Worlds-Crash-Course-with-Laex05-Now-Available/td-p/1303353. The solution I went with was I used a Map. The key is the player and the value is the stats.
So player enters the world
I have this:
cuiStats_Data.playerStatsMap.set(player, playerStats); cuiStats_Data.playerStatsBinding.set(playerStats, [player]); this.connectNetworkEvent(player, collectHealth, (data: { health: number, player: Player }) => { this.handleHealthUpdate(data.health, data.player); })handleHealthUpdate looks like this
private handleHealthUpdate(health: number, player: Player): void { var tempPlayerStats = cuiStats_Data.playerStatsMap.get(player); if (tempPlayerStats) { tempPlayerStats.healthPercentage += health; cuiStats_Data.playerStatsBinding.set(tempPlayerStats, [player]) } }This place where I would want to call this event, I would do
this.sendNetworkEvent(player, collectHealth, {health: this.props.numberToUpgrade, player: player} ); }Thank you to everyone who provided ideas and solutions!