estybite
(estybite)
January 9, 2025, 3:03am
1
I created a UI in UEFN and placed a button and a text block. I want to implement functionality using Verse so that clicking the button inputs text into the adjacent text block.
I have reviewed the official tutorials and believe I understand the basics, but the tutorials do not explain how to bring UI elements like buttons and text blocks into Verse.
Could you please explain how to import these UI elements into Verse or provide guidance on how to implement this functionality?
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())