Would Start With Some Base Object Like This
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /Verse.org/Colors }
button_text_block := struct:
TextBlock : text_block
Button : text_button_base
(ButtonTextBlock:button_text_block).ClickedEvent():listenable(widget_message)=
return ButtonTextBlock.Button.OnClick()
ConstructButtonTextBlock(ButtonText:string, DefaultText:string):button_text_block=
TextBlock := text_block:
DefaultTextColor := color{R := 1.0, G := 1.0, B := 1.0}
DefaultText := DefaultText.ToMessage()
Button := button_loud:
DefaultText := ButtonText.ToMessage()
ButtonTextBlock := button_text_block:
TextBlock := TextBlock
Button := Button
return ButtonTextBlock
(ButtonTextBlock:button_text_block).ToStackBoxSlot():stack_box_slot=
StackBox := stack_box:
Orientation := orientation.Horizontal
Slots := array:
stack_box_slot{Widget := ButtonTextBlock.Button}
stack_box_slot{Widget := ButtonTextBlock.TextBlock}
for(Slot:Slots){StackBox.AddWidget(Slot)}
OutStackBoxSlot := stack_box_slot{Widget := StackBox}
return OutStackBoxSlot
(ButtonTextBlock:button_text_block).ClickTask(ExitEvent:listenable(widget_message))<suspends>:void=
var Clicks : int = 0
race:
block:
ExitEvent.Await()
block:
loop:
ButtonTextBlock.ClickedEvent().Await()
set Clicks += 1
ButtonTextBlock.TextBlock.SetText("{Clicks}".ToMessage())
Sleep(0.0) # You can remove this if you want
Would then make some base class for ui
StringToMessage<localizes>(String:string):message="{String}"
(String:string).ToMessage():message={return StringToMessage(String)}
player_ui_base := class:
Owner : player
MainOverlay : overlay = overlay{}
ContainsButtons : logic
Show():void=
InputMode := player_ui_slot{InputMode := if(ContainsButtons?){ui_input_mode.All} else{ui_input_mode.None}}
if(PlayerUI := GetPlayerUI[Owner]):
PlayerUI.AddWidget(MainOverlay, InputMode)
Hide():void=
if(PlayerUI := GetPlayerUI[Owner]):
PlayerUI.RemoveWidget(MainOverlay)
Initialize():void=
block{}
Finally you could make some sub class that has buttons and build out the ui / use the object i created above
button_text_ui_test := class(player_ui_base):
NumBlocks : int
var ButtonTextBlocks : []button_text_block = array{}
ContainsButtons <override> : logic = true
ExitButton : text_button_base = button_loud{}
ExitEvent():listenable(widget_message)={return ExitButton.OnClick()}
Initialize<override>():void=
for(i := 0..NumBlocks):
ButtonTextBlock := ConstructButtonTextBlock("Button {i}", "")
set ButtonTextBlocks += array{ButtonTextBlock}
HorizontalSlots := for(ButtonTextBlock:ButtonTextBlocks){ButtonTextBlock.ToStackBoxSlot()}
MainStackBox := stack_box{Orientation := orientation.Vertical}
for(Slot:HorizontalSlots){MainStackBox.AddWidget(Slot)}
OverlaySlot := overlay_slot{Widget := MainStackBox}
ExitButton.SetText("EXIT".ToMessage())
ExitButtonSlot := overlay_slot{Widget := ExitButton}
MainOverlay.AddWidget(ExitButtonSlot)
MainOverlay.AddWidget(OverlaySlot)
ButtonTask()<suspends>:void=
Show()
for(ButtonTextBlock:ButtonTextBlocks):
spawn{ButtonTextBlock.ClickTask(ExitEvent())}
ExitEvent().Await()
Hide()
But most importantly you can really just pass a button / text_block into a method that has an exit condition, wait for the button to be clicked and then set the text on it however you’d like
you could really just do
(Button:text_button_base).AwaitInteraction(TextBlock:text_block, ExitEvent:listenable(widget_message))<suspends>:void=
race:
block:
ExitEvent.Await()
block:
loop:
Button.OnClick().Await()
TextBlock.SetText("SomeText".ToMessage())