SsimnJS Docs

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 Difficulty group: 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:

FieldsIn the WBP
MusicHover, EasyHover, NormalHover, HardHover, VolumeDownHover, VolumeHover, VolumeUpHover, PlayHover, ResetHoverRender Opacity of a lighter shape over each control.
VolumeDownPressed, VolumeUpPressed, PlayPressed, ResetPressedRender Opacity of a flash over the button, for a moment on each click.
MusicOn, EasyOn, NormalOn, HardOnRender Opacity of the check of Music and of the fill of the selected difficulty.
VolumeFillWidth Override of the SizeBox that holds the fill bar of the slider.
VolumeValueThe position of the slider, from 0 to 1.
VolumeTextThe 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
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
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.

On this page