GetPlayerUI<native><public>(Player:player)<transacts><decides>:player_ui
# The main interface for adding and removing `widget`s to a player's UI.
player_ui<native><public> := class<final><epic_internal>:
# Adds `Widget` to this `player_ui` using default `player_ui_slot` configuration options.
AddWidget<native><public>(Widget:widget):void
# Adds `Widget` to this `player_ui` using `Slot` for configuration options.
AddWidget<native><public>(Widget:widget, Slot:player_ui_slot):void
# Removes `Widget` from this `player_ui`.
RemoveWidget<native><public>(Widget:widget):void
# Sets the user's focus on this `Widget`. The target `Widget`must be focusable, otherwise this has no effect.
# If `SetFocus` is called before `AddWidget`, the `widget` will be focused after `AddWidget` is called,
# unless a SetFocus is called on a different `widget` by the time `AddWidget` is called.
SetFocus<native><public>(Widget:widget):voidUnrealEngine.digestには上記のような関数とクラスが定義されています。Verse由来のUIとウィジェットブループリントの両方は、このクラスを経由して表示/非表示を管理します。
GetPlayerUI
「GetPlayerUI」関数を使用することで、プレイヤーのUI情報を管理するクラスである「player_ui」にアクセスできます。
# 例1
if:
PlayerUI := GetPlayerUI[Player]
then:
# 例2
OnInteract(Agent:agent):void=
if:
Player := player[Agent]
PlayerUI := GetPlayerUI[Player]
then:GetPlayerUIの引数には「player型」のクラスを入れます。多くの場合、仕掛けのイベントからプレイヤー自身でもある「agent」クラスにアクセスできるので、それを「player[agent]」とキャストして、GetPlayerUIの引数に渡します。
当然ですが、NPCや野生動物のようなagentはplayerではありませんので、このifは失敗します。
二つのAddWidgetと二つのモード
player_uiクラスには、引数が一つの「AddWidget」と、引数が二つの「AddWidget」が存在しています。
AddWidgetの引数には「widgetクラス」が求められており、これは「canvas」や「Assets.digest」からアクセスできるウィジェットブループリントはwidgetクラスを継承しているため、引数に入れることができます(当然、今あげたもの以外もwidgetクラスを継承していればなんでも入れられます)
NewCanvas := canvas:
Slots := array:
# canvas_slotを記述
PlayerUI.AddWidget(NewCanvas)のように、ウィジェットを入れることができます。引数が一つのAddWidgetは、「ui_input_mode」が「None」の状態でUIの表示がされます。これは、キャラクターの操作やカメラの移動に影響させない、情報を表示させるだけのUIを作り出せます。
PlayerUI.AddWidget(NewCanvas, player_ui_slot{InputMode := ui_input_mode.All})と、第二引数にplayer_ui_slotクラスを入れてあげ、InputModeに「ui_input_mode.All」の指定をしてあげると、UIボタンやスライダーのような要素を操作できる、インタラクト可能なUIを表示できます。
PlayerUI.AddWidget(NewCanvas, player_ui_slot{InputMode := ui_input_mode.None})ちなみに、Noneとすれば、第二引数を省略したAddWidgetと同じく「UIボタンやスライダーを触れない」UIとなります。これは、単純に省略したか、きちんと明示して書くかの違いです。
UI非表示
var CurrentCanvas:?widget = false
ShowUI(Player:player):void=
if:
PlayerUI := GetPlayerUI[Player]
then:
NewCanvas := canvas:
Slots := array:
# UI要素を記述
PlayerUI.AddWidget(NewCanvas)
set CurrentCanvas = option{NewCanvas}
HideUI(Player:player):void=
if:
Canvas := CurrentCanvas?
PlayerUI := GetPlayerUI[Player]
then:
PlayerUI.RemoveWidget(Canvas)
set CurrentCanvas = falseRemoveWidget機能を使用することで、UIを非表示することができます。
注意点として「表示したときと同じクラスのインスタンス」を入れてあげる必要があります。
# ダメな例
Canvas := canvas:
Slots := array:
# UI要素を記述
PlayerUI.AddWidget(Canvas)
NewCanvas := canvas:
Slots := array:
# UI要素を記述
PlayerUI.RemoveWidget(NewCanvas)例えば、RemoveWidgetを呼び出す際に新しくcanvasクラスを作成し、RemoveWidgetに入れたとしても、UI要素は非表示になりません。
見た目は同じ構成で同じクラスを入れているようですが、中身は別のタイミングで作成した別のクラスなので、Verse側で現在表示中のUIとは別物として判定されるからです。
この辺の概念が難しい…という方は、今の段階で無理に理解しなくても問題ないです!残りのチャプターを進めていくと、自然と理解が深まっていくと思いますので…。