buttonクラスって?
# Button is a container of a single child widget slot and fires the OnClick event when the button is clicked.
button<native><public> := class<final>(widget):
# The child widget of the button. Used only during initialization of the widget and not modified by SetSlot.
Slot<native><public>:button_slot
# Sets the child widget slot.
SetWidget<native><public>(InSlot:button_slot):void
# Subscribable event that fires when the button is clicked.
OnClick<public>():listenable(widget_message) = external {}
HighlightEvent<public>():listenable(widget_message) = external {}
UnhighlightEvent<public>():listenable(widget_message) = external {}UnrealEngine.digest.verseには「button」と呼ばれるクラスが定義されています。「button_loud」や「button_quiet」と普段なじみのあるデザインではなく、完全に自作のデザインにすることができるボタンです。
きほんの「き」
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Colors }
# ひとり用なのでマルチ未対応
button_sample_device<public> := class(creative_device):
ButtonColorBlock:color_block = color_block:
DefaultDesiredSize := vector2{X := 256.0, Y := 64.0}
DefaultColor := NamedColors.Gray
OnBegin<override>()<suspends>:void=
if:
FirstPlayer := GetPlayspace().GetPlayers()[0]
then:
ShowButtonUI(FirstPlayer)
ShowButtonUI(InPlayer:player):void=
if:
PlayerUI := GetPlayerUI[InPlayer]
then:
NewButton := button:
Slot := button_slot:
Widget := ButtonColorBlock
NewCanvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.9}
Maximum := vector2{X := 0.5, Y := 0.9}
Alignment := vector2{X := 0.5, Y := 0.5}
Widget := NewButton
NewButton.HighlightEvent().Subscribe(OnHighlighted)
NewButton.UnhighlightEvent().Subscribe(OnUnhighlighted)
NewButton.OnClick().Subscribe(OnClicked)
PlayerUI.AddWidget(NewCanvas, player_ui_slot{InputMode := ui_input_mode.All})
OnHighlighted(WidgetMessage:widget_message):void=
ButtonColorBlock.SetColor(NamedColors.White)
OnUnhighlighted(WidgetMessage:widget_message):void=
ButtonColorBlock.SetColor(NamedColors.Gray)
OnClicked(WidgetMessage:widget_message):void=
Print("ボタンを押したよ!")まずは実際の使用例を見た方が理解しやすいと思うので、簡単なサンプルを用意しました(わかりやすさ重視でマルチは未対応です!そのままつかわないでね( •̀ ω •́ )✧)
まずはbuttonをつくる!
buttonを作成すると、Slotの中身を要求されます。Slotは「button_slot」型となっています。
# Slot for button widget.
button_slot<native><public> := struct:
# The widget assigned to this slot.
Widget<native><public>:widget
# Horizontal alignment of the widget inside the slot.
HorizontalAlignment<native><public>:horizontal_alignment = external {}
# Vertical alignment of the widget inside the slot.
VerticalAlignment<native><public>:vertical_alignment = external {}
# Empty distance in pixels that surrounds the widget inside the slot. Assumes 1080p resolution.
Padding<native><public>:margin = external {}じゃあ、button_slotってなんぞやって話ですが。基本はWidgetにはデザインとして使用する別のwidgetクラスを入れます。今回の例では「color_block」を使用していますが、overlayとtext_blockを組み合わせて文字付きボタンを作ってみたり、ウィジェットブループリントを入れて凝ったデザインにしてみたり。
NewButton := button:
Slot := button_slot:
Widget := {デザイン用のウィジェット}サンプルからbuttonを作る箇所だけ取り出したのが上記のコードです。よーわからんって方は、とりあえず何個かデザイン違いを作ってみてなれるとか…してみましょう!サンプルコードの「ButtonColorBlock」をtext_blockとかにしてみるのも面白いですよ!
canvasで使用する
buttonはwidgetクラスなので、canvas_slot内で使用することができます。記事の趣旨から外れてしまうので、canvas_slotやwidgetクラスのあれこれは説明しきれませんが、とりあえずbutton_loud系統のやつと同じ感覚で使えます。
NewCanvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.9}
Maximum := vector2{X := 0.5, Y := 0.9}
Alignment := vector2{X := 0.5, Y := 0.5}
Widget := NewButton今回の例ですと画面下部中央に表示するみたいな感じです。
サブスクライブ
buttonクラスの真骨頂である「HighlightEvent」と「UnhighlightEvent」についてです。これらは簡単に説明すると「ボタンをホバーした際」と「ホバーが解除された際」にイベントを発信するlistenableです。
例えばマウスプレイヤーの場合は、マウスをボタンの位置に合わせた場合にHighlightEventが発信され、ボタンの位置から外れたらUnhighlightEventが発信されます。同様に、コントローラープレイヤーの場合は、ボタンを選択するとHighlightEventが発信され、別のボタンなどを選択するとUnhighlightEventが発信されます。
あとは、通常のボタン同様にOnClickも用意されているので、ボタンを押したら○○をするみたいな実装もできます。
OnHighlighted(WidgetMessage:widget_message):void=
ButtonColorBlock.SetColor(NamedColors.White)
OnUnhighlighted(WidgetMessage:widget_message):void=
ButtonColorBlock.SetColor(NamedColors.Gray)
OnClicked(WidgetMessage:widget_message):void=
Print("ボタンを押したよ!")では、HighlightEventとUnhighlightEventが発信された場合の処理も見てみましょう。これらは基本的に「今選択中であるか」をプレイヤーに伝える目的で使用するため、色を差し替えたり、サイズを調整したり、プレイヤー目線で分かりやすい変化を持たせるのがおすすめです。
まあ、デザイン変更にとらわれず、ホバーのたびにダメージを食らうみたいなのもできますので…ここは皆様の発想力でいい感じの実装をしましょう!
きほんの「ほ」
では、ちょっとした応用みたいなのを紹介します。

Verse FieldでHighlightの状態を渡す用の変数を作ります(今回はlogicにしましたが、intでもっと色んな状態を管理したりだとか?)

で、Verse Fieldを設定するとwidgetクラスとその変数を持ったウィジェットブループリントのクラスが公開されるので
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Colors }
# ひとり用なのでマルチ未対応
button_sample_device<public> := class(creative_device):
BlueprintWidget:WBP_Button = WBP_Button{}
OnBegin<override>()<suspends>:void=
if:
FirstPlayer := GetPlayspace().GetPlayers()[0]
then:
ShowButtonUI(FirstPlayer)
ShowButtonUI(InPlayer:player):void=
if:
PlayerUI := GetPlayerUI[InPlayer]
then:
NewButton := button:
Slot := button_slot:
Widget := BlueprintWidget
NewCanvas := canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.9}
Maximum := vector2{X := 0.5, Y := 0.9}
Alignment := vector2{X := 0.5, Y := 0.5}
Widget := NewButton
NewButton.HighlightEvent().Subscribe(OnHighlighted)
NewButton.UnhighlightEvent().Subscribe(OnUnhighlighted)
PlayerUI.AddWidget(NewCanvas, player_ui_slot{InputMode := ui_input_mode.All})
OnHighlighted(WidgetMessage:widget_message):void=
set BlueprintWidget.IsHighlighted = true
OnUnhighlighted(WidgetMessage:widget_message):void=
set BlueprintWidget.IsHighlighted = falseそれを、button_slotのウィジェットで渡してあげることで、ウィジェットブループリントでデザインしたカスタムVerseボタンを作ることができます。
実際にどう見えるか
今回のサンプルコードをゲーム内で見たらどうなるかです。ちゃんとマウスを向けたら色変わってるよね!