Quick start
Try the kit with the demo settings panel.
The kit includes a demo widget, WBP_WorldUIKit_Demo: a settings panel with a music switch, three difficulty choices,
a volume slider with โ and + buttons, a Play button and a Reset button. Like your own widgets, it shows its hover,
clicks and states itself, from the Verse fields its layout writes: the kit draws nothing over it.
Place the demo
After installing the kit, drag WorldUIKit/Widgets/WBP_WorldUIKit_Demo into the
level. Set its scale to 10 and turn it to face the spawn.
Add three components
Select the widget entity and add, in the Details panel:
interactive_widget_component: the kit;world_ui_kit_demo_layout: where the elements are, and the fields of the WBP;world_ui_kit_demo_logic: what Play and Reset do.
Play
Launch a session and aim at the panel.
What to try
- Music is a toggle: each click switches it on or off.
- Easy, Normal and Hard are choices of the
Difficultygroup: only one is selected. - Volume is a slider from 0 to 100 in steps of 5. Hold fire and move the crosshair to drag it, or click where the value should go. The โ and + buttons are steppers that move it by one step.
- Play prints the current settings in the log.
- Reset puts the music, the difficulty and the volume back.
Then set States to PerPlayer on interactive_widget_component: each player keeps their own settings.
The demo's fields
WBP_WorldUIKit_Demo has 20 Verse fields, all written by its layout:
| Fields | In the WBP |
|---|---|
MusicHover, EasyHover, NormalHover, HardHover, VolumeDownHover, VolumeHover, VolumeUpHover, PlayHover, ResetHover | Render Opacity of a lighter shape over each control. |
VolumeDownPressed, VolumeUpPressed, PlayPressed, ResetPressed | Render Opacity of a flash over the button, for a moment on each click. |
MusicOn, EasyOn, NormalOn, HardOn | Render Opacity of the check of Music and of the fill of the selected difficulty. |
VolumeFill | Width Override of the SizeBox that holds the fill bar of the slider. |
VolumeValue | The position of the slider, from 0 to 1. |
VolumeText | The value shown next to the slider. |
Open the WBP and Window > View Bindings to see each binding.
The demo layout
The layout is a component that returns the size of the widget and its elements, and writes the fields of the WBP. It is exactly what the editor writes for a widget with these effects.
world_ui_kit_demo_layout<public> := class<final_super>(component, interactive_layout, interactive_fields):
GetLayout<override>()<transacts>:interactive_layout_data =
interactive_layout_data{Width := 1200.0, Height := 760.0, Elements := array{
interactive_element{Name := "Music", Kind := interactive_kind.Toggle, X := 1072.0, Y := 190.0, Width := 64.0, Height := 64.0, Prompt := "Music on / off", StartOn := true},
interactive_element{Name := "Easy", Kind := interactive_kind.Choice, X := 662.0, Y := 292.0, Width := 150.0, Height := 60.0, Group := "Difficulty"},
interactive_element{Name := "Normal", Kind := interactive_kind.Choice, X := 824.0, Y := 292.0, Width := 150.0, Height := 60.0, StartOn := true, Group := "Difficulty"},
interactive_element{Name := "Hard", Kind := interactive_kind.Choice, X := 986.0, Y := 292.0, Width := 150.0, Height := 60.0, Group := "Difficulty"},
interactive_element{Name := "VolumeDown", Kind := interactive_kind.Stepper, X := 640.0, Y := 390.0, Width := 64.0, Height := 64.0, Prompt := "Volume down", Target := "Volume", Steps := -1},
interactive_element{Name := "Volume", Kind := interactive_kind.Slider, X := 720.0, Y := 402.0, Width := 336.0, Height := 40.0, MaxValue := 100.0, Step := 5.0, StartValue := 60.0},
interactive_element{Name := "VolumeUp", Kind := interactive_kind.Stepper, X := 1072.0, Y := 390.0, Width := 64.0, Height := 64.0, Prompt := "Volume up", Target := "Volume"},
interactive_element{Name := "Play", Kind := interactive_kind.Button, X := 420.0, Y := 540.0, Width := 360.0, Height := 100.0, Prompt := "Play", Cooldown := 1.0},
interactive_element{Name := "Reset", Kind := interactive_kind.Button, X := 996.0, Y := 562.0, Width := 140.0, Height := 56.0, Prompt := "Reset settings"}}}
SetHovered<override>(Widget:entity, Element:string, On:logic):void =
if (W := Widgets.WBP_WorldUIKit_Demo_entity[Widget]):
Value := if (On?) then 1.0 else 0.0
case (Element):
"Music" => set W.MusicHover = Value # Render Opacity of the widget to show
"Easy" => set W.EasyHover = Value # Render Opacity of the widget to show
"Normal" => set W.NormalHover = Value # Render Opacity of the widget to show
"Hard" => set W.HardHover = Value # Render Opacity of the widget to show
"VolumeDown" => set W.VolumeDownHover = Value # Render Opacity of the widget to show
"Volume" => set W.VolumeHover = Value # Render Opacity of the widget to show
"VolumeUp" => set W.VolumeUpHover = Value # Render Opacity of the widget to show
"Play" => set W.PlayHover = Value # Render Opacity of the widget to show
"Reset" => set W.ResetHover = Value # Render Opacity of the widget to show
_ => {}
SetPressed<override>(Widget:entity, Element:string, On:logic):void =
if (W := Widgets.WBP_WorldUIKit_Demo_entity[Widget]):
Value := if (On?) then 1.0 else 0.0
case (Element):
"VolumeDown" => set W.VolumeDownPressed = Value # Render Opacity of the widget to show
"VolumeUp" => set W.VolumeUpPressed = Value # Render Opacity of the widget to show
"Play" => set W.PlayPressed = Value # Render Opacity of the widget to show
"Reset" => set W.ResetPressed = Value # Render Opacity of the widget to show
_ => {}
SetOn<override>(Widget:entity, Element:string, On:logic):void =
if (W := Widgets.WBP_WorldUIKit_Demo_entity[Widget]):
Value := if (On?) then 1.0 else 0.0
case (Element):
"Music" => set W.MusicOn = Value # Render Opacity of the widget to show
"Easy" => set W.EasyOn = Value # Render Opacity of the widget to show
"Normal" => set W.NormalOn = Value # Render Opacity of the widget to show
"Hard" => set W.HardOn = Value # Render Opacity of the widget to show
_ => {}
SetValue<override>(Widget:entity, Element:string, Value:float, Fraction:float, Text:string):void =
if (W := Widgets.WBP_WorldUIKit_Demo_entity[Widget]):
case (Element):
"Volume" =>
set W.VolumeValue = Fraction # 0..1 along the slider
set W.VolumeFill = Fraction * 336.0 # Width Override of the fill (a SizeBox)
set W.VolumeText = InteractiveText(Text)
_ => {}
SetEnabled<override>(Widget:entity, Element:string, On:logic):void = {}
SetScreen<override>(Widget:entity, Screen:int):void = {}
# Per-player copies (States = PerPlayer): a fresh widget of the same WBP.
NewCopy<override>():?entity = option{Widgets.WBP_WorldUIKit_Demo_entity{}}The demo logic
The logic subscribes to the clicks of the kit and reacts to Play and Reset. ?Player := option{Event.Player} targets
the player who clicked when States is PerPlayer.
world_ui_kit_demo_logic<public> := class<final_super>(component):
var Subscription<private>:?interactive_subscription = false
OnBeginSimulation<override>():void =
if (Kit := Entity.GetComponent[interactive_widget_component]):
Clicks := Kit.SubscribeClicked(OnClicked)
set Subscription = option{Clicks}
OnEndSimulation<override>():void =
if (S := Subscription?) then S.Cancel()
set Subscription = false
OnClicked(Event:interactive_event):void =
Kit := Event.Widget
case (Event.Element):
"Reset" =>
Kit.SetOn("Music", true, ?Player := option{Event.Player})
Kit.SetOn("Normal", true, ?Player := option{Event.Player})
Kit.SetValue("Volume", 60.0, ?Player := option{Event.Player})
"Play" =>
Music := if (Kit.IsOn["Music", ?Player := option{Event.Player}]) then "on" else "off"
Volume := Kit.GetValue("Volume", ?Player := option{Event.Player})
Print("[world-ui-kit demo] play: music {Music}, volume {Volume}")
_ => {}Next
- Examples: three more widgets to place and copy from: a shop with per-player gold, a code keypad, a radio.
- Online editor: make your own widget clickable.
- Effects and animations: let your WBP animate its own buttons.