[UEFN]VerseでUIを作成して表示する方法
仕組み
PlayerにUIが紐づいていて、UIのWidgetにCanvasを設置できる
CanvasにはWidgetを複数設定できる
構造的には下記のイメージ
Player
└PlayerUI
└Canvas Widget
└Widget(ButtonやImageなどをSlotで割り当て)
実装方法
PlayerからUIを取得して、取得したPlayerUIにWidgetを設定したCanvasを割り当てる。
CanvasのスロットにWidgetを配置し、PlayerにAdd
例えば、
Overlay TyepeのWidgetを表示したければ、CanvasのSlotのWidgetプロパティに設定して
そのCanvasをユーザーに割り当てる。
配置場所は、各SlotのAnchors, Alignment, Offsets, SizeToContentで設定
CanvasにCanvasを割り当てることもできます
参考ドキュメント:
・Widgetの種類
・割り当て方の公式docs
・Colors
各色のイメージ
例
MyButtonは別途レベル上のオブジェクトと紐づける必要あり
紐づけ方:
カスタム型をエディタに公開する
Verseファイルの作成やビルドは下記参照:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/SpatialMath}
using { /Verse.org/Colors }
custom_ui_canvas := class(creative_device):
# ボタンの仕掛けをエディタ内で設定して、レベル内でその仕掛けを参照するようにします
@editable
MyButton : button_device = button_device{}
# UI にテキストとして表示するローカライズ可能なメッセージ
TextForMyUI<localizes>(InText : string) : message = "{InText}"
# プレイヤーと、そのプレイヤーの UI に追加されている可能性があるウィジェットとの間のマッピング
# キーがplayerでvalueがcanvas
var MaybeMyUIPerPlayer : [player]?canvas = map{}
# 実行中のゲームで仕掛けが開始されたときに実行します
OnBegin<override>()<suspends> : void =
MyButton.InteractedWithEvent.Subscribe(HandleButtonInteraction)
# カスタム仕様の UI は特定のプレイヤーのみに関連付けることができ、そのプレイヤーのみが表示できます
HandleButtonInteraction(Agent : agent) : void =
# エージェントはプレイヤーか AI にすることができますが、取得できるのはプレイヤーの UI のみであるため、
# プレイヤー タイプには、ボタンの仕掛けとやり取りしたエージェントをキャストする必要があります
if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):
# プレーヤーにウィジェットが表示されているかどうかを確認
if (MyUI := MaybeMyUIPerPlayer[InPlayer]?):
PlayerUI.RemoveWidget(MyUI)
if (set MaybeMyUIPerPlayer[InPlayer] = false) {}
else:
NewUI := CreateMyUI()
PlayerUI.AddWidget(NewUI)
if (set MaybeMyUIPerPlayer[InPlayer] = option{NewUI}) {}
# テキスト付きのボタンを画面のさまざまな位置に表示するキャンバス ウィジェット
CreateMyUI() : canvas =
MyCanvas : canvas = canvas:
Slots := array:
canvas_slot: # 画面左上, Button
Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.0}, Maximum := vector2{X := 0.0, Y := 0.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 0.0}
SizeToContent := true
Widget := button_loud{DefaultText := TextForMyUI("Upper Left")}
canvas_slot: # 画面中央上, Button
Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.0}, Maximum := vector2{X := 0.5, Y := 0.0} }
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.5, Y := 0.0}
SizeToContent := true
Widget := button_loud{DefaultText := TextForMyUI("Upper Middle")}
canvas_slot: # 画面右上, Button
Anchors := anchors{Minimum := vector2{X := 1.0, Y := 0.0}, Maximum := vector2{X := 1.0, Y := 0.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 1.0, Y := 0.0}
SizeToContent := true
Widget := button_loud{ DefaultText := TextForMyUI("Upper Right")}
canvas_slot: # 画面左中央, Button
Anchors := anchors{ Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y := 0.5}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 0.5}
SizeToContent := true
Widget := button_loud{DefaultText := TextForMyUI("Middle Left")}
canvas_slot: # 画面中央, Button
Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.5}, Maximum := vector2{X := 0.5, Y := 0.5}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.5, Y := 0.5}
SizeToContent := true
Widget := button_loud{DefaultText := TextForMyUI("Center")}
canvas_slot: # 画面右中央, CanvasにCanvasを配置
Anchors := anchors{Minimum := vector2{X := 1.0, Y := 0.5}, Maximum := vector2{X := 1.0, Y := 0.5}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 1.0, Y := 0.5}
SizeToContent := true
Widget := canvas:
Slots := array:
canvas_slot: # 画面左上
Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.0}, Maximum := vector2{X := 0.0, Y := 0.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 0.0}
SizeToContent := true
Widget := overlay:
Slots := array:
overlay_slot:
Widget := color_block:
DefaultColor := NamedColors.AliceBlue
DefaultOpacity := 1.0
DefaultDesiredSize := vector2{X := 1024.0, Y := 128.0}
overlay_slot:
Widget := text_block:
DefaultText := TextForMyUI("俊足")
canvas_slot: # 画面左下, Slider
Anchors := anchors{Minimum := vector2{X := 0.0, Y := 1.0}, Maximum := vector2{X := 0.0, Y := 1.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.0, Y := 1.0}
SizeToContent := true
Widget := slider_regular:
DefaultValue := 5.0
DefaultMinValue := 0.0
DefaultMaxValue := 10.0
DefaultStepSize := 0.5
canvas_slot: # 画面中央下, ColorBlock
Anchors := anchors{ Minimum := vector2{X := 0.5, Y := 1.0}, Maximum := vector2{X := 0.5, Y := 1.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.5, Y := 1.0}
SizeToContent := true
Widget := color_block:
DefaultColor := NamedColors.CornflowerBlue
DefaultOpacity := 1.0
DefaultDesiredSize := vector2{X := 128.0, Y := 128.0}
canvas_slot: # 画面右下, Overlay
Anchors := anchors{Minimum := vector2{X := 1.0, Y := 1.0}, Maximum := vector2{X := 1.0, Y := 1.0}}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 1.0, Y := 1.0}
SizeToContent := true
Widget := overlay:
Slots := array:
overlay_slot:
Widget := color_block:
DefaultColor := NamedColors.MintCream
DefaultOpacity := 1.0
DefaultDesiredSize := vector2{X := 1024.0, Y := 128.0}
overlay_slot:
Widget := text_block:
DefaultText := TextForMyUI("This is my text block overlaying a color block.")
return MyCanvas
UI作成の疑問
・UEFNのBluePrintから作成したUIをVerseで使用して動的に値を変更できるか?
→
現時点ではできなさそう
Can you access a created Widget BP within verse?
https://forums.unrealengine.com/t/can-you-access-a-created-widget-bp-within-verse/1192748
下記動画を参考にしてできそう
(別途解説記事を書こうと思います)
その他参考URL
Custom UI / HUD
Discussion