

Verse解説の続きを教えてほしいです!

初心者向けにわかりやすく解説してほしいですね!
こんなお悩みを解決します。
本記事の内容この記事を書いている僕は、クリエイター兼ブロガーです。実際に現在進行形でUEFNを学んでいます。
今回は、UIボタンの作り方のVerse(5)について解説します。
なお、1,2,3,4を見ていない方は先に1,2,3,4から進めましょう。
-
-
【UEFN】UIボタンの作り方を画像付きで徹底解説【Verse言語】
続きを見る
-
-
【UEFN】UIボタンの作り方(2ページ目)│Verse解説の続き
続きを見る
-
-
【UEFN】UIボタンの作り方(3ページ目)│Verse解説の続き
続きを見る
-
-
【UEFN】UIボタンの作り方(4ページ目)│Verse解説の続き
続きを見る
※以下のコードの解説文は、プログラミング初心者の主が調べながら記述したものです。
コードの解釈に誤りがありましたら恐縮ですm(_ _)m
参考程度にどうぞ。
それでは、さっそくやっていきましょう。

もくじ
- 1 UIボタンの作り方(5ページ目)│Verse解説の続き
- 2 よくある質問
- 2.1 今回のメンバーについて教えて!
- 2.2 今回の関数について教えて!
- 2.3 CreateMyUIとReturnCanvasSlotsの役割の違い
- 2.4 DeleteUIとHandleSelectedUIButtonの関係性
- 2.5 HandleSelectedUIButtonとFindButtonUIの関係性
- 2.6 FindButtonUI(ボタンを探す)の役割について深掘り
- 2.7 HandleSelectedUIButtonとActivateTriggerの関係性
- 2.8 buttonui := class():の詳細
- 2.9 ボタンUIクラスの定義について
- 2.10 concrete指定子とは
- 2.11 @editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}を小数点で入力している理由
- 2.12 buttonchoice_intの詳細
- 2.13 @editable var RemovesUIOnClick :&@editable SaveButtonStateの詳細
- 2.14 @editable ButtonSignal_Recieve&@editable ButtonSignal_Sendの詳細
- 2.15 ButtonUI_UserOptions_Functions := class<concrete>():の詳細
- 2.16 ButtonUI_UserOptions_Functions := class<concrete>():の詳細
- 2.17 @editable SendInstigator : logic = trueの詳細
- 2.18 FindButtonUI関数とSendInstigator変数の目的と違い
- 2.19 var SizeToContent : logic = falseの詳細
- 2.20 var ButtonWidgetPerPlayer : [agent]widget = map{}の詳細
- 2.21 var EnabledStateMap&var VisibleStateMapの詳細
- 3 まとめ
UIボタンの作り方(5ページ目)│Verse解説の続き
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =の詳細
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
if (ThisButtonUI.SaveButtonState?):
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
このコードは、Agent
に関連したウィジェット(ボタン)の状態を読み込むための処理を行うものです。
以下で具体的な動作を解説します。
ThisButtonUI.SaveButtonState
がオンになっているかをチェックします。これは、ボタンの状態を保存するためのフラグです。- もし
SaveButtonState
がオンの場合、ThisButtonUI.ButtonWidgetPerPlayer
からAgent
に関連したウィジェットを取得します。 - ウィジェットの有効状態を取得し、ウィジェットに適用します。具体的には、
ThisButtonUI.EnabledStateMap
からAgent
に関連した有効状態を取得し、ThisWidget.SetEnabled(ThisEnabledState)
を呼び出すことで、ウィジェットの有効状態を設定します。 - ウィジェットの可視状態を取得し、ウィジェットに適用します。
ThisButtonUI.VisibleStateMap
からAgent
に関連した可視状態を取得し、その値に基づいて適切な可視性を設定します。
- もし
ThisVisibleState
がtrue
の場合、ThisWidget.SetVisibility(widget_visibility.Visible)
を呼び出してウィジェットを表示します。 - もし
ThisVisibleState
がfalse
の場合、ThisWidget.SetVisibility(widget_visibility.Collapsed)
を呼び出してウィジェットを非表示にします。 - 上記以外の場合(
_
)は、エラーメッセージを表示します。
- もしウィジェットの取得に失敗した場合は、エラーメッセージを表示します。
このコードの目的は、ボタンの状態を保存しておき、Agent
に関連したウィジェットを読み込んで有効状態と可視状態を復元することです。
各種状態は ThisButtonUI
内のマップ(EnabledStateMap
や VisibleStateMap
)に保存されている想定です。
このコードは、あるボタンの状態を保存する(セーブする)ためのものです。そして、セーブされた状態を再び読み込んでボタンの表示や動作を復元することができます。
例えば、あるゲームでポーズを表すボタンがあります。プレイヤーがポーズボタンを押すと、ゲームが一時停止し、それに応じてボタンの見た目や動作が変化します。このセーブ機能を使えば、ゲームを終了しても再度プレイする際に、前回のポーズの状態を復元することができるのです。
このコードでは、まずボタンのセーブ状態を確認します。
セーブされている場合は、プレイヤーやゲーム操作者(Agent)に関連付けられたボタンのウィジェット(ボタンの見た目や動作を管理する部分)を取得します。
次に、ウィジェットの「有効」状態や「可視」状態を読み込んで設定します。有効状態は、ボタンを押せるかどうかを表し、可視状態は、ボタンを見えるようにするかどうかを表します。
もしウィジェットの取得に問題があった場合は、エラーメッセージが表示されます。
つまり、このコードはボタンの状態を保存し、再度読み込むことでボタンの見た目や動作を復元するためのものです。
これによって、前回の設定や操作を覚えておくことができます。

例えば、ゲームやアプリで「前回の設定を復元する」という機能を使ったことがあるかもしれません。
このコードは、そのような機能の一部を実現するためのものです。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void
は、プログラム内で特定のエージェント( agent
)に属する特定のボタン( buttonui
)の状態を復元するための関数です。
エージェント( agent
)は、プログラム内の特定の要素やオブジェクトを表しています。この関数は、エージェントが持つボタン( buttonui
)の状態を復元するために使用されます。
関数の目的は、ボタンの状態を復元することです。つまり、以前保存されたボタンの状態を取得し、ボタンにそれを適用します。
関数は以下の手順で処理されます:
- 引数の
buttonui
には、復元したい特定のボタンが渡されます。 - 指定されたボタンのセーブ状態を確認します。
- セーブ状態は、以前の保存時にボタンの特定の属性の値が保存されている場所です。
- ボタンがセーブされているかどうかを確認します。
- もしボタンがセーブされていない場合、既定の値を使用してボタンを初期化します。
- もしボタンがセーブされている場合、関連する属性や状態を元の値に復元します。
- これには、ボタンの有効状態や表示状態などが含まれます。
- 復元した属性や状態を、指定されたボタンに適用します。
- これにより、ボタンの見た目や機能が元の保存された状態に戻ります。
最後に、関数の戻り値が void
となっています。これは、この関数が何も返さないことを意味します。つまり、関数が実行された後、戻り値を使用して他の処理を行う必要はありません。
簡単に言えば、この関数は特定のエージェントが持つ特定のボタンの状態を復元するために使われるものです。
ボタンのセーブ状態を確認し、保存された属性や状態を元に戻すことで、ボタンが以前の状態に戻ります。
身近な例えとしては、ゲームのセーブデータを使って、プレイヤーが前回プレイした場所やアイテムなどを復元することが挙げられます。セーブデータに保存された情報を読み込んで、プレイヤーの状態を復元するわけです。
if (ThisButtonUI.SaveButtonState?):の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
if (ThisButtonUI.SaveButtonState?):
は、プログラム内の条件文(if
文)で、ThisButtonUI
の SaveButtonState
という属性がオン(存在する)かどうかをチェックします。
if
文は、指定された条件が真(true)の場合に、その条件内のコードブロックを実行します。
具体的に解説すると:
ThisButtonUI
は特定のボタンを表す変数やオブジェクトです。SaveButtonState
はボタンの属性で、ボタンの状態を保存するために使用される属性です。?
は「オプショナルチェイニング演算子」と呼ばれ、属性が存在するかどうかをチェックします。SaveButtonState
属性がオン(存在する)場合、つまりその属性が定義されている場合、条件は真となります。
- オン(存在する)の例:
ThisButtonUI.SaveButtonState
が存在するかつ真(true)の値を持つ場合
- オフ(存在しない)の例:
ThisButtonUI.SaveButtonState
が存在しない、または偽(false)の値を持つ場合
if
文の条件が真の場合、条件内のコードブロックが実行されます。条件内のコードブロックは、if
文の後にインデントされた部分です。
要するに、これは特定のボタン(ThisButtonUI
)の SaveButtonState
属性がオン(存在する)かどうかをチェックしています。条件が真の場合は、条件内のコードブロックが実行されます。
例えば、ボタンの状態を保存するための属性が有効に設定されていて、ThisButtonUI.SaveButtonState
が定義されている場合に、条件は真となります。
例えるなら、ボタンが特定の設定オプションを持っているかどうかを確認し、それに応じて特定の処理を実行するといった感じです。

if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent])
の部分は、Pythonのウォルラス演算子(Walrus operator)と呼ばれる機能を使用しています。
ウォルラス演算子は、変数に値を代入しつつ、その値を条件式で評価するための便利な構文です。
具体的には、以下の解説を参考にしてください:
ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、ThisButtonUI
のButtonWidgetPerPlayer
辞書からAgent
に関連するウィジェットを取得する操作です。if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent])
は、以下のように構成されています:
ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
の評価結果をThisWidget
という変数に格納します。- この代入式全体の評価結果は、
ThisWidget
に格納された値となります。
- その後、if文の条件式として
if (ThisWidget)
が評価されます。- この条件式の結果は、
ThisWidget
に格納された値の真偽に基づいて決まります。 - もし
ThisWidget
が空でない(値が存在する)場合は真となります。
- この条件式の結果は、
- もし条件式が真の場合、
ThisWidget
にはウィジェットが格納されているという意味です。- その場合は、インデントされたブロック内のコードが実行されます。
このウォルラス演算子を使うことで、変数の値を直接条件式で評価しながら代入できるため、コードが簡潔になります。
たくさん「取得」「適用」とか記載されていますけど、要はこれ、元の状態を1つずつ復元させているということです。

if (ThisEnabledState := ~(ThisEnabledState)の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
の部分は、次のように解釈できます。
ThisButtonUI.EnabledStateMap[Agent]
は、ThisButtonUI
の中のEnabledStateMap
という辞書(マップ)から、キーとしてAgent
を使用して値を取得しています。:=
は、代入演算子です。これにより、取得した値がThisEnabledState
に代入されます。if (ThisEnabledState):
は、ThisEnabledState
の値を条件として評価し、その結果に基づいて次のブロックを実行するかどうかを判断します。
つまり、上記のコードのこの部分は、ThisButtonUI.EnabledStateMap
から Agent
に関連するウィジェットの有効状態を取得し、それが存在すれば(ThisEnabledState
が真であれば)、ThisWidget.SetEnabled(ThisEnabledState)
を実行して、ウィジェットの有効状態を設定しています。
具体的に言えば、これは次のような処理フローとなります:
ThisButtonUI.EnabledStateMap
からAgent
に関連するウィジェットの有効状態を取得します。- もし有効状態が取得された場合(
ThisEnabledState
が真であれば)、その状態を使って、ThisWidget
(取得したウィジェット)の有効状態を設定します。- 具体的な設定方法は、
ThisWidget.SetEnabled()
メソッドで行われます。
- 具体的な設定方法は、
このコードは、特定のボタンに紐づくエージェントの有効状態を保存しておき、ロードした際に復元するためのものです。
また、エラー処理として、有効状態の取得に失敗した場合はエラーメッセージを出力します。

ウィジェットの取得とは
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
まず、このコードは、特定のボタン(ThisButtonUI
)に関連するエージェント(Agent
)に対して、ウィジェットの状態を読み込むための処理です。
- まず、
ThisButtonUI.SaveButtonState
がオンになっているかどうかをチェックします。- これは、ボタンの状態を保存するためのフラグであり、もしオン(真)であれば、状態を読み込む処理を続けます。
- 次に、
ThisButtonUI.ButtonWidgetPerPlayer[Agent]
を使って、エージェントに関連するウィジェットを取得します。- ウィジェットは、ユーザーインターフェース(UI)上でボタンなどの操作や表示を行うための要素です。
- ウィジェットの有効状態を取得するために、
ThisButtonUI.EnabledStateMap[Agent]
を使います。EnabledStateMap
は、エージェントごとに設定されたウィジェットの有効(操作可能な)状態を示すマップです。
ThisWidget.SetEnabled(ThisEnabledState)
を使って、取得した有効状態(ThisEnabledState
)をウィジェットに適用します。- つまり、ウィジェットの操作可能かどうかを設定することができます。
- 同様に、ウィジェットの可視状態も取得します。
ThisButtonUI.VisibleStateMap[Agent]
は、エージェントごとに設定されたウィジェットの可視(表示)状態を示すマップです。 ThisWidget.SetVisibility(widget_visibility.Visible)
やThisWidget.SetVisibility(widget_visibility.Collapsed)
を使って、取得した可視状態に基づいてウィジェットの表示状態を適用します。- 具体的には、可視状態が
true
(真)であれば、ウィジェットを表示し、false
(偽)であれば非表示にします。
- 具体的には、可視状態が
このコードでは、特定のボタンの状態を保存しておき、その保存された状態をロードするための処理を行っています。ウィジェットの有効状態と可視状態は、保存された状態に基づいて適用され、ユーザーインターフェースの表示や操作を復元します。
もしウィジェットの取得に失敗した場合(ThisButtonUI.ButtonWidgetPerPlayer[Agent]
が存在しない場合)、エラーメッセージが出力されます。これは、ウィジェットが正しく設定されていないか、存在しないことを示しています。
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):は、エージェントをキーとしてボタンの有効状態を取得。
ThisWidget.SetEnabled(ThisEnabledState)は、有効状態であった場合に、その状態をウィジェットに適用させるコードデス。

SetEnabled関数の詳細
クリックすると開きます。
SetEnabled関数は、プレイヤーがウィジェットとやり取りできるかどうかを有効または無効にするための関数です。この関数を使用すると、ウィジェットのインタラクションを制御することができます。
パラメータとしてInIsEnabled(ロジック)というものを受け取ります。このパラメータは、ウィジェットの有効化または無効化を指定します。
InIsEnabledには論理値(trueまたはfalse)を指定します。
trueを指定すると、ウィジェットが有効になり、プレイヤーはそれと対話することができます。falseを指定すると、ウィジェットが無効になり、プレイヤーはそれと対話することができません。
これにより、ゲーム内の特定の条件に応じてウィジェットの有効化または無効化を制御し、ユーザーが必要な時にのみウィジェットと対話できるようにすることができます。

ウィジェットのインタラクションを制御することは、プレイヤーがウィジェットとどのようにやり取りできるかを管理することを指します。
具体的には、ウィジェットがクリックやタップなどのユーザーの入力を受け付けるかどうか、または特定の条件や状態に応じてウィジェットが利用可能かどうかを制御することです。
例えば、ゲーム内のメニュー画面にボタンがある場合、特定のイベントが発生するまではそのボタンを無効化しておき、イベントが発生した時点でボタンを有効化することができます。
また、ゲーム内のキャラクターのスキルが特定のレベル以上でないと使えない場合、スキルボタンを無効化しておき、必要なレベルに達した時点で有効化することも可能です。
ウィジェットの有効化または無効化を適切に制御することで、プレイヤーに適切なタイミングで必要な操作を行わせることができます。
それによって、ゲームの流れやプレイヤーの体験をより制御しやすくすることができます。

if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
まず、この行は「ThisButtonUI.VisibleStateMap[Agent]」というマップ(連想配列)からAgentに関連する値を取得し、それを「ThisVisibleState」という変数に代入しています。
条件式の評価はその後行われます。すなわち、「ThisVisibleState」が何らかの値(None
以外の値)を持っている場合、条件式の評価がTrueとなります。
つまり、連想配列「ThisButtonUI.VisibleStateMap」にAgentに関連するキーが存在し、それに対応する値が存在する場合にTrueとなります。
この構文を用いることで、変数の初期化と条件式の評価を1行で行い、スッキリとしたコードを記述することができます。
例えば、「ThisButtonUI.VisibleStateMap」は、ゲームのボタンの可視性情報を保持している連想配列で、Agentはプレイヤーを表しています。
この行では、特定のプレイヤーに関連付けられたボタンの可視性状態を取得しています。「ThisButtonUI.VisibleStateMap[Agent]」は、Agent(プレイヤー)に関連付けられたボタンの可視性状態を表します。
もしAgentに関連するボタンの可視性情報が存在する場合、条件式がTrueとなります。
case (ThisVisibleState):~の取得に失敗しました")の詳細
クリックすると開きます。
(Agent: agent).LoadButtonState(ThisButtonUI: buttonui): void =
# このThisButtonUIのSaveButtonStateがオンになっているかチェックする
if (ThisButtonUI.SaveButtonState?):
# Agentに関連するウィジェットを取得する
if (ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# ウィジェットの有効状態を取得し適用する
if (ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
# ウィジェットの可視状態を取得し適用する
if (ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
# ThisVisibleStateの値に基づいて適切な可視性を適用する
case (ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
else:
Print("~ERROR: ウィジェットの取得に失敗しました!")
この部分では、「ThisVisibleState」という変数の値に基づいて、異なる可視性を適用するための条件分岐が行われます。この変数の値には、通常真偽値(true
またはfalse
)が想定されています。
コードの意味を解説すると、以下のようになります。
case (ThisVisibleState):
:ThisVisibleState
の値に基づいて条件を判定するためのラベルです。
true => ThisWidget.SetVisibility(widget_visibility.Visible)
:- もし
ThisVisibleState
がtrue
と等しい場合、ThisWidget
の可視性をwidget_visibility.Visible
に設定します。
- もし
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
:- もし
ThisVisibleState
がfalse
と等しい場合、ThisWidget
の可視性をwidget_visibility.Collapsed
に設定します。
- もし
_ => Print("~ERROR: 'ThisVisibleState'の取得に失敗しました")
:- 上記のいずれの条件にも当てはまらない(デフォルトの場合)場合、エラーメッセージを出力します。
上記の例では、ThisVisibleState
の値に応じて ThisWidget
の可視性を切り替えています。
例えば、ゲームのボタンの表示状態を制御するコードだと考えましょう。
もし ThisVisibleState
が true
ならばボタンを表示(Visible
)し、false
ならばボタンを非表示(Collapsed
)にし、上記の条件に当てはまらない場合はエラーメッセージを出力します。
SetVisibility関数の詳細
クリックすると開きます。
SetVisibility関数は、ウィジェットの表示状態を制御するための関数です。この関数を使用すると、ウィジェットを表示したり非表示にしたりすることができます。
以下に、SetVisibility関数の詳細を解説します。
- SetVisibility関数は、引数としてwidget_visibility(ウィジェットの可視性)を受け取ります。
- widget_visibilityは、Unreal Engine(アンリアル エンジン)の仕組みで、ウィジェットの表示状態を表す列挙型です。
- 使用可能なwidget_visibilityの値には、以下のようなものがあります(具体的な値はUnreal Engineの公式ドキュメントを参照してください):
- Visible:
- ウィジェットを表示します。
- Collapsed:
- ウィジェットを非表示にしますが、ウィジェット自体は削除しません。
- Hidden:
- ウィジェットを非表示にします。非表示にしたウィジェットはレイアウトやイベントに参加しません。
- SetVisibility関数はvoid(戻り値なし)型です。
- つまり、何かしらの処理結果を返すわけではありません。
したがって、以下のようにSetVisibility関数を使うことができます。
ThisWidget.SetVisibility(widget_visibility.Visible); // ウィジェットを表示する
ThisWidget.SetVisibility(widget_visibility.Collapsed); // ウィジェットを非表示にする
SetVisibility関数はウィジェットの表示状態を制御するためのもので、引数に「表示するか非表示にするか」の情報を指定します。ウィジェットを表示する場合は「Visible」を、非表示にする場合は「Collapsed」を指定します。
例えば、ゲームのUIでボタンをクリックしたときに対応するウィジェットの表示状態を切り替えたい場合に、SetVisibility関数を使用することができます。

widget_visibility列挙型は、Unreal Engine(アンリアル エンジン)のウィジェットの表示状態を表すために使用される列挙型です。ウィジェットの表示/非表示やレイアウトへの影響を制御するために、SetVisibility関数などのメソッドで使用されます。
以下に、widget_visibility列挙型の詳細を解説します。
- widget_visibilityは、3つの列挙子(定数)から構成されています。
- Visible:
- ウィジェットが表示され、レイアウト空間を占有します。
- つまり、ユーザーに見える状態です。
- この状態では、ウィジェットは他のウィジェットと共に画面上で配置されます。
- Collapsed:
- ウィジェットが見えない状態で、レイアウト空間を占有しません。
- つまり、非表示にされていますが、ウィジェット自体は削除されず、レイアウトの再計算に影響を与えません。
- Hidden:
- ウィジェットが見えない状態で、レイアウト空間を占有します。
- つまり、非表示にされていますが、ウィジェットの領域が他のウィジェットによって使用されることを防ぎます。
- Hidden状態のウィジェットは、レイアウトやイベントの処理から除外されます。
したがって、この列挙型を使用することで、ウィジェットの表示状態を柔軟に制御することができます。ウィジェットの表示や非表示、他のウィジェットとの関連付けなど、ユーザーインターフェースの振る舞いを細かく設定する際に便利です。
わかりやすく説明すると、widget_visibility列挙型はウィジェットの表示状態を表すものです。
Visibleはウィジェットが見える状態、Collapsedはウィジェットが見えない状態でレイアウトに影響を与えない状態、Hiddenはウィジェットが見えない状態でレイアウトに影響を与える状態を表します。
例えば、ゲームのメニュー画面で一部のウィジェットを一時的に隠したい場合に、SetVisibility関数にCollapsedを指定してウィジェットを非表示にすることができます。

よくある質問
今回のメンバーについて教えて!
クリックすると開きます。

今回の材料(メンバー)
- `buttonchoice_int`:
- ボタンスタイルの選択を制約するカスタム型です。
- `menumanagerdevice`:
- `creative_device`を継承したクラスで、UIメニューを管理するためのデバイスです。
- `TriggerToShowUI`:
- UIメニューを表示するためのトリガーデバイス。
- `ButtonUI`:
- エディタで設定可能なボタンUIの配列。
- `MaybeMyUIPerPlayer`:
- プレーヤーごとにキャンバスの存在を保持する辞書型変数。
- `StringToMessage`:
- 指定された文字列をメッセージに変換するメソッド。
- `OnBegin`:
- `override`修飾子を持つ`creative_device`クラスのメソッドをオーバーライドしており、初期化とUIの表示のトリガー処理を行います。
これらのメンバーは、UIメニューを管理するためのデバイスや機能を提供するために利用されるものです。
特に注目すべきは、buttonchoice_int
というカスタム型で、ボタンスタイルの選択を制約する役割があります。この説明からは、ボタンスタイルに関するオプションが限定されることがわかります。
menumanagerdevice
はcreative_device
を継承したクラスであり、UIメニューを管理するのに使用されます。
これにより、UIの表示や管理に関する機能を含むコードがまとめられています。
TriggerToShowUI
は、UIメニューを表示するためのトリガーデバイスです。
このトリガーが発生することで、UIを表示するための処理が開始されることが期待されます。
ButtonUI
はエディタで設定可能なボタンUIの配列を表します。
この配列は、異なる種類のボタンUIや設定を管理するのに使用されるでしょう。
MaybeMyUIPerPlayer
はプレーヤーごとにキャンバスの存在を保持する辞書型変数です。
これにより、各プレーヤーに対して独自のUIを管理することができます。
StringToMessage
は指定された文字列をメッセージに変換するためのメソッドです。
これは、ユーザーに対して表示されるテキストを処理するために使用されます。
また、OnBegin
メソッドは、creative_device
クラスのメソッドをオーバーライドしており、初期化とUIの表示のトリガー処理を行います。
つまり、デバイスの開始時に実行される特定の処理や、UIメニューの表示を開始するためのトリガーになることが期待されます。
これらのメンバーは、UIメニューを作成、表示、制御するための機能やデータを提供しており、UIの操作や表示に関連するコードを効率的に管理することができます。

今回の関数について教えて!
クリックすると開きます。

今回の主な料理人(関数)は以下のとおりです。
- 1. OnBegin<override>()<suspends>:void=
- InitButtonFunctions()関数を呼び出し、TriggerToShowUIイベントがトリガーされた場合にOpenUI関数をサブスクライブします。
- 2. OpenUI(Agent : ?agent):void=
- 指定されたエージェントのプレイヤーに対してUIを表示または更新します。
- エージェントに対して適切なボタンUIを作成し、それを含むキャンバスを返します。
- 3. CreateMyUI(Agent : agent) : canvas =
- エージェントのためのキャンバススロットの配列を返します。
- これにより、エージェントに適切なUIを作成し配置するための準備が整います。
- 4. ReturnCanvasSlots(Agent : agent):[]canvas_slot=
- キャンバススロットの配列を返します。
- これにより、UIを配置するための空きスロットがわかります。
- 5. DeleteUI(Message : widget_message) : void=
- 指定されたメッセージに対応するUIを削除します。
- エージェントから不要なUIを取り除く際に使用します。
- 6. HandleSelectedUIButton(Message : widget_message):void=
- 選択されたボタンUIに対する処理を行います。
- ユーザーがボタンを押したときなどに、選択されたボタンに対して特定のアクションを実行するために使用します。
- 7. (Agent : agent).FindButtonUI(ThisWidget : widget):?buttonui=
- 指定されたエージェントに関連付けられたボタンUIを検索して返します。
- エージェントに対して作成されたボタンUIの情報を取得する際に使用します。
- 8. (ThisButtonUI : buttonui).ActivateTrigger(Player : player):void=
- 指定されたボタンUIのトリガーをアクティブ化し、プレーヤーに対してトリガーを発生させます。
- ボタンを押したときに関連するアクションをトリガーするために使用します。
- 9. (Agent : agent).LoadButtonState(ThisButtonUI : buttonui):void=
- 'SaveButtonState' がオンになっているすべてのボタン状態を読み込みます。
- 前回のセッションやプレイの状態を復元する際に、保存されたボタンの状態を読み込むために使用します。
- 10. InitButtonFunctions():void=
- 各ボタンUIの 'functions' タブを初期化します。
- ボタンUIの機能設定を初期化するために使用します。
これらの関数は、UIの作成・表示・削除・操作など、ユーザーインターフェースに関連する様々な操作を行うために使用される機能です。
エージェントのプレイヤーに対してUIを管理し、ボタンUIの動作や状態などを制御することができます。

buttonuiクラス内で定義されている関数は以下のとおり。
- 1. EnableWidget(Agent : ?agent):void=
- ボタンUIを有効化し、ボタンをクリック可能にします。
- 2. DisableWidget(Agent : ?agent):void=
- ボタンUIを無効化し、ボタンをクリック不可にします。
- 3. (Agent : agent).SaveEnabledState(State : logic):void=
- ボタンの現在の有効状態を指定のエージェントに対して保存します。
- 4. ShowWidget(Agent : ?agent):void=
- ボタンUIを表示し、ボタンを可視化します。
- 5. HideWidget(Agent : ?agent):void=
- ボタンUIを非表示にし、ボタンを非表示にします。
- 6. (Agent : agent).SaveVisibleState(State : logic):void=
- ボタンの現在の可視状態を指定のエージェントに対して保存します。
これらの関数は、ボタンUIの状態管理や操作を行うための処理を提供しています。
ボタンの有効状態の保存、表示・非表示の切り替えなどの機能が含まれています。
CreateMyUIとReturnCanvasSlotsの役割の違い
クリックすると開きます。
# エージェントに対してボタンUIを作成し、それを含むキャンバスを返します。
CreateMyUI(Agent : agent) : canvas =
for(CurrButtonUI : ButtonUI):
case(CurrButtonUI.ButtonStyle):
1 =>
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
2 =>
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
3 =>
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
_ =>
Print("~ERROR: ButtonStyle integer over/under-flow")
CanvasArray := ReturnCanvasSlots(Agent)
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
return MyInteractableButtons
# エージェントのためのキャンバススロットの配列を返します。
ReturnCanvasSlots(Agent : agent):[]canvas_slot=
var CanvasSlotArray : []canvas_slot = array{}
for(ThisButtonUI : ButtonUI):
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
Agent.LoadButtonState(ThisButtonUI)
ThisSlot := canvas_slot:
Offsets := margin{Top := ThisButtonUI.ButtonPosition.Y, Left := ThisButtonUI.ButtonPosition.X, Bottom := ThisButtonUI.ButtonSize.Y, Right := ThisButtonUI.ButtonSize.X}
ZOrder := 0
SizeToContent := ThisButtonUI.SizeToContent
Widget := ThisWidget
set CanvasSlotArray += array{ThisSlot}
return CanvasSlotArray
これらの関数は、ボタンUIの作成、エージェントへの関連付け、キャンバススロットの作成と設定など、ボタンUIの管理を行うための一連の処理を提供しています。
CreateMyUI
関数では、ボタンUIを作成してエージェントに関連付けた後、キャンバスを作成して返します。
ReturnCanvasSlots
関数では、エージェントに関連付けられたボタンUIを使用してキャンバススロットの配列を作成し、返します。
これにより、エージェントに対して適切なボタンUIが表示されるキャンバスが作成されます。
詳細は以下のとおりです。
CreateMyUI(Agent: agent) : canvas
:
- 役割:
- エージェントに対してボタンUIを作成し、それを含むキャンバスを作成して返します。
- 処理の流れ:
ButtonUI
内の各ボタンUI(CurrButtonUI
)についてループします。CurrButtonUI.ButtonStyle
の値によって、異なるスタイルのボタンUIを作成します。- ボタンUIのクリックイベントに
HandleSelectedUIButton
を登録します。 - 作成したボタンUIを対応するエージェント(
Agent
)に関連付けます。
ReturnCanvasSlots(Agent)
を呼び出して、エージェントのキャンバススロットの配列を取得します。- キャンバスを作成し、取得したキャンバススロットの配列を含めて返します。
ReturnCanvasSlots(Agent: agent): []canvas_slot
:
- 役割:
- エージェントのためのキャンバススロットの配列を返します。
- 処理の流れ:
- 空の配列
CanvasSlotArray
を作成します。
- 空の配列
ButtonUI
内の各ボタンUI(ThisButtonUI
)についてループします。- エージェント
Agent
に対して関連付けられたボタンUIThisWidget
を取得します。 LoadButtonState(ThisButtonUI)
を呼び出して、ボタンUIの状態(有効/無効、可視/非可視)をエージェントに読み込みます。- キャンバススロット
ThisSlot
を作成し、適切なプロパティ(配置やサイズなど)と関連付けられたボタンUIを設定します。 CanvasSlotArray
にThisSlot
を追加します。
- エージェント
- 最終的に、キャンバススロットの配列
CanvasSlotArray
を返します。
【イメージ】
CreateMyUI
関数とReturnCanvasSlots
関数は、ゲーム作りのための役割を持っています。
Imagineあなたがゲームのデザイナーだとしましょう。ゲーム内にはボタンがありますよね。
それぞれのボタンを作るときに、ボタンの見た目(スタイル)を決める必要がありますし、ボタンがクリックされたときに何が起こるのかも指定する必要があります。
CreateMyUI
関数は、デザイナー(あなた)がボタンを作って、ゲーム内のキャンバス(ボタンが置かれるスペース)を作る役割を持っています。
具体的には、以下のような手順でボタンを作ります。
- ボタンのスタイルを選んで決めます。
- たとえば、好きな色や形を指定することができます。
- ボタンがクリックされたときに実行される関数(アクション)を指定します。
- たとえば、ボタンがクリックされたらキャラクターがジャンプするといったような動作を設定します。
- ボタンを作ったら、それをゲームのキャンバスに配置します。
- キャンバスはボタンが置かれる場所のことです。
ReturnCanvasSlots
関数は、デザイナー(あなた)が作ったボタンをゲームのキャンバスに配置する役割を持っています。
具体的には、以下のような手順でキャンバスの設定を行います。
- ゲーム内に存在するボタンを確認します。
- 各ボタンの位置や大きさを指定し、キャンバス上のスロット(配置場所)を作ります。
- ボタンをそれぞれのスロットに配置します。
つまり、CreateMyUI
関数はボタンの作成とキャンバスの作成を担当し、ReturnCanvasSlots
関数はボタンの配置を担当しています。
この二つの関数は協力して、ゲーム内にボタンを追加し、それらをキャンバス上に配置するのに役立ちます。

DeleteUIとHandleSelectedUIButtonの関係性
クリックすると開きます。
# 指定されたメッセージに対応するUIを削除。
DeleteUI(Message : widget_message) : void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
PlayerUI.RemoveWidget(MyUI)
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
# 選択されたボタンUIに対する処理を行います。
HandleSelectedUIButton(Message : widget_message):void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
ThisWidget := Message.Source
StaleButtonUI := Player.FindButtonUI(ThisWidget)
if(ThisButtonUI := StaleButtonUI?):
if(ThisButtonUI.RemovesUIOnClick?):
DeleteUI(Message)
ThisButtonUI.ActivateTrigger(Player)
else:
Print("~ERROR: No buttonui found!")
両者の違いは、DeleteUI関数はUIの削除のみを担当し、HandleSelectedUIButton関数はボタンUIに対する具体的な処理を行います。
HandleSelectedUIButton関数では、ボタンのクリック時にUIの削除とその他のアクションの実行が行われます。
「DeleteUI(Message: widget_message): void」関数は、指定されたメッセージに対応するUIを削除する役割を持っています。
具体的な手順は以下のとおり。
- プレイヤーに対応するPlayerUIとMaybeMyUIPerPlayer[Message.Player](プレイヤーごとのUI)を取得します。
- もしPlayerUIとMaybeMyUIPerPlayer[Message.Player]が存在する場合、以下の処理を行います。
- PlayerUIからMaybeMyUIPerPlayer[Message.Player]に対応するUI(MyUI)を削除します。
- MaybeMyUIPerPlayer[Message.Player]をfalseに設定します。
「HandleSelectedUIButton(Message : widget_message): void」関数は、選択されたボタンUIに対する処理を行う役割を持っています。
具体的な手順は次の通りです。
- プレイヤーに対応するPlayerUIとMaybeMyUIPerPlayer[Message.Player](プレイヤーごとのUI)を取得します。
- もしPlayerUIとMaybeMyUIPerPlayer[Message.Player]が存在する場合、以下の処理を行います。
- プレイヤーをMessage.Playerとして設定します。
- 選択されたボタンUIをThisWidgetとして設定します。
- プレイヤーが保持しているボタンUIの中からThisWidgetに対応するUI(StaleButtonUI)を取得します。
- もしStaleButtonUIが存在する場合、以下の処理を行います。
- もしThisButtonUI.RemovesUIOnClickがtrueであれば、DeleteUI(Message)を呼び出してUIを削除します。
- ThisButtonUIに関連付けられたアクション(トリガー)を実行します。
- もしStaleButtonUIが存在しない場合、"~ERROR: No buttonui found!"というエラーメッセージが表示されます。
DeleteUI関数は、HandleSelectedUIButton関数内で条件によって呼び出されることがあるわけですね。
具体的には、HandleSelectedUIButton関数内で選択されたボタンUIのThisButtonUIに対して、RemovesUIOnClickがtrueの場合にUI削除が行われます。

【イメージ】
あなたはドラゴンが出てくる冒険ゲームをプレイしています。ゲームにはドラゴンを倒すためのボタンが表示されます。
このボタンをクリックすると、ドラゴンに攻撃が行われます。
DeleteUI関数について:
- DeleteUI関数は、ゲーム画面に表示されるもの(例えば、ボタンやテキストなど)を消す役割があります。
- これは、プレイヤーが冒険の途中でボタンを不要になった場合や、特定のイベントが終了した後などに便利です。
- たとえば、冒険が終わった後にボタンを非表示にするためにDeleteUI関数が使われます。
HandleSelectedUIButton関数について:
- HandleSelectedUIButton関数は、プレイヤーがボタンをクリックしたときに何を行うかを決める役割があります。
- 例えば、プレイヤーがドラゴンを倒すためのボタンをクリックした場合、HandleSelectedUIButton関数がそのイベントを処理します。
- この関数では、ドラゴンに対する攻撃やスコアの更新など、様々なアクションを行うことができます。
DeleteUIとHandleSelectedUIButtonの関係:
- DeleteUI関数は、HandleSelectedUIButton関数内で特定の条件が満たされた場合に呼び出されることがあります。
- 例えば、プレイヤーがドラゴンを倒した後にボタンを非表示にする必要がある場合、HandleSelectedUIButton関数内でDeleteUI関数を使ってボタンの削除を行います。
- これにより、プレイヤーがドラゴンを倒した後にボタンが消える仕組みが実現されます。
つまり、DeleteUI関数はボタンや他のUIを消すための関数であり、HandleSelectedUIButton関数はボタンクリック時のアクションを処理するための関数です。


HandleSelectedUIButton関数内で特定の条件がそろった場合に、DeleteUI関数が呼び出されることでUIが削除され、ゲームの進行や表示の制御が行われるわけですね🌸
このような仕組みを通じて、ゲームの操作や表示を柔軟に制御することができます。
HandleSelectedUIButtonとFindButtonUIの関係性
クリックすると開きます。
# 選択されたボタンUIに対する処理を行います。
HandleSelectedUIButton(Message : widget_message):void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
ThisWidget := Message.Source
StaleButtonUI := Player.FindButtonUI(ThisWidget)
if(ThisButtonUI := StaleButtonUI?):
if(ThisButtonUI.RemovesUIOnClick?):
DeleteUI(Message)
ThisButtonUI.ActivateTrigger(Player)
else:
Print("~ERROR: No buttonui found!")
# 指定されたエージェントに関連付けられたボタンUIを検索して返します。
(Agent : agent).FindButtonUI(ThisWidget : widget):?buttonui=
for(ThisButtonUI : ButtonUI):
if(StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if(ThisWidget = StaleWidget):
return option{ThisButtonUI}
return false
HandleSelectedUIButton関数とFindButtonUI関数は、ゲームにおけるボタンの操作や管理に関わる関数です。
HandleSelectedUIButton関数は、プレイヤーがボタンをクリックしたときに何を行うかを処理するための関数です。
詳細は以下のとおり。
- プレイヤーが関連付けられたボタンUIを持っているかを確認します。
- もし持っていれば、そのプレイヤーと関連付けられたUIを変数に格納します。
- プレイヤーの情報やクリックされたボタンの情報を取得し、一時的に保存します。
- ボタンの情報が古くなっていないかを確認します。
- もし古くなっていた場合、ボタンUIを削除する設定があるかを確認し、DeleteUI関数を呼び出してボタンUIを削除します。
- ボタンUIに紐づいたトリガー(特定のアクションを起こすための条件)をアクティブにします。
- ボタンが見つからなかった場合は、エラーメッセージを表示します。
FindButtonUI関数は、指定されたプレイヤーに関連付けられたボタンUIを探すための関数です。
詳細は以下のとおりです。
- 指定されたプレイヤーに関連付けられたボタンUIを1つずつチェックします。
- チェック中のボタンUIに対応するウィジェット(ボタンのこと)が存在するかを確認します。
- ウィジェットが見つかった場合、そのボタンUIを返します。
- ウィジェットが見つからなかった場合、falseを返します。
つまり、HandleSelectedUIButton関数はプレイヤーがボタンをクリックしたときの処理を担当し、FindButtonUI関数は指定されたプレイヤーに関連付けられたボタンUIを探す役割を持っています。

このような仕組みを通じて、ボタンのクリックや関連付けられたアクションの処理が行われ、ゲームの進行やプレイヤーの操作が制御されるのです。
【イメージ】
「アドベンチャーゲーム」を想定して、ボタンを使ってゲーム内のキャラクターを移動させる場面を考えてみます。
プレイヤーがボタンをクリックすると、ゲーム内のキャラクターが上に移動する仕組みを作りましょう。
以下にそれを表現するためのコードを示します。
Agent: ゲーム内のキャラクター
class ButtonUI:
ButtonWidgetPerPlayer: プレイヤーごとに関連付けられたボタンのウィジェット
RemovesUIOnClick: ボタンクリック時にUIを削除するかどうか
# その他のプロパティやメソッド
PlayerUI: プレイヤーごとのUI
MaybeMyUIPerPlayer: プレイヤーごとに関連付けられたUI
def HandleSelectedUIButton(Message):
if PlayerUI := GetPlayerUI(Message.Player) and MyUI := MaybeMyUIPerPlayer.get(Message.Player):
Player := Message.Player
ThisWidget := Message.Source
StaleButtonUI := Player.FindButtonUI(ThisWidget)
if ThisButtonUI := StaleButtonUI:
if ThisButtonUI.RemovesUIOnClick:
DeleteUI(Message)
ThisButtonUI.ActivateTrigger(Player)
else:
Print("~ERROR: No buttonui found!")
def Agent.FindButtonUI(ThisWidget):
for ThisButtonUI in ButtonUI:
if StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer.get(Agent):
if ThisWidget == StaleWidget:
return ThisButtonUI
return None
このコードでは、以下のような関係性が表現されています。
- プレイヤーがボタンをクリックしたとき、
HandleSelectedUIButton
関数が呼び出されます。 HandleSelectedUIButton
関数内では、FindButtonUI
関数を使って、クリックされたボタンに関連付けられたボタンUIを探します。- ボタンUIが見つかった場合、関連付けられたキャラクターを上に移動させるためのトリガー(ActivateTrigger)がアクティブにされます。
- 同時に、もしボタンUIがクリック時に削除される設定になっている場合、
DeleteUI
関数が呼び出されてUIが削除されます。 - ボタンUIが見つからなかった場合、エラーメッセージが表示されます。
このように、HandleSelectedUIButton
関数とFindButtonUI
関数が連携して、ボタンクリックに応じたアクションやUIの管理を行っています。
たとえば、プレイヤーが「上に移動するボタン」をクリックすると、ボタンUIがアクティブになり、それに関連付けられたキャラクターが上に移動するといった具体的なゲームの動作が実現されるのです。

FindButtonUI(ボタンを探す)の役割について深掘り
クリックすると開きます。
想像してみてください。あなたが学校で友達と一緒に遊ぶゲームを作っているとします。
そのゲームは、各自が自分のボタンを持っていて、そのボタンを押すと特定の効果が起こるとします。
あなたたちはゲームを遊ぶときに、各自が持っているボタンを押すことでキャラクターをジャンプさせたいと思っています。
しかし、問題は誰がどのボタンを持っているのかを知る必要があることです。
そこで、「FindButtonUI(ボタンを探す)」という役割のお友達を一人用意しました。
このお友達はとても頭が良く、他の人が持っているボタンを見て、どのボタンが誰のものなのかを教えてくれるんです。
たとえば、あなたは「私のボタンを探してほしい!」と言うと、お友達はあなたが持っているボタンを見つけて、それを教えてくれます。「これがあなたのボタンだよ!」と言ってくれるわけです。
これによって、あなたは自分が押すべきボタンを正確に知ることができます。
あなたがボタンを押したいときに、お友達に教えてもらったボタンを押すことで、ゲームのキャラクターがジャンプするようになるんです。
コンピューターのプログラムでも同じような仕組みが使われています。プログラムの中には、各プレイヤーが持っているボタンを探し出す役割を持った関数(例えば、FindButtonUI関数)があります。
この関数は、指定されたプレイヤーのボタンを見つけて、それをほかの場所で使うために教えてくれるのです。
つまり、FindButtonUI関数は、「どのプレイヤーがどのボタンを持っているのか」を見つける役割を果たし、その情報を使って正しいボタンを押すことができるようになるのです。

FindButtonUI関数がないと、プレイヤーは自分がどのボタンを押したのか、どのボタンが自分のものなのか正確に判断することができません。
ゲームやアプリでは、プレイヤーがボタンをクリックすることで特定のアクションが起こる場合があります。
例えば、ジャンプするボタンを押すとキャラクターがジャンプするといった具体的なアクションがあります。
もしもFindButtonUI関数がないと、プログラムは「誰がボタンを押したのか?」や「押されたボタンはどのボタンなのか?」といった情報を正確に把握することができません。
その結果、プレイヤーが意図したアクションを実行することができなくなってしまいます。
例えば、プレイヤーAがジャンプするためのボタンをクリックしたとします。しかし、FindButtonUI関数がない場合、プログラムはどのボタンがプレイヤーAに関連付けられているのかを把握できません。
そのため、プレイヤーAのジャンプアクションを正しく処理することができません。
つまり、FindButtonUI関数がないと、プレイヤーがどのボタンを押したのかわからず、正確にキャラクターを操作することができません。
関連付けられたボタンを見つけることは、プレイヤーがゲームやアプリを楽しくプレイするために非常に重要な要素です。

HandleSelectedUIButtonとActivateTriggerの関係性
クリックすると開きます。
# 選択されたボタンUIに対する処理を行います。
HandleSelectedUIButton(Message : widget_message):void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
ThisWidget := Message.Source
StaleButtonUI := Player.FindButtonUI(ThisWidget)
if(ThisButtonUI := StaleButtonUI?):
if(ThisButtonUI.RemovesUIOnClick?):
DeleteUI(Message)
ThisButtonUI.ActivateTrigger(Player)
else:
Print("~ERROR: No buttonui found!")
# 指定されたボタンUIのトリガーをアクティブ化し、プレーヤーに対してトリガーを発生させます。
(ThisButtonUI : buttonui).ActivateTrigger(Player : player):void=
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
if(ThisSignalDestination.SendInstigator?):
ThisSignalDestination.TriggerToActivate.Trigger(Player)
ThisSignalDestination.TriggerToActivate.Trigger()
これらの関数は、プレイヤーが選択したボタンUIに対して処理を行い、トリガーなどのイベントを発生させる役割を持っています。
これによって、ボタンをクリックした際にプレイヤーに対して特定のアクションやイベントを実行することができます。
詳細は以下のとおり。
HandleSelectedUIButton関数(選択されたボタンUIの処理を行う関数)
- 目的:
- プレイヤーが選択したボタンUIに対して処理を行うための関数です。
- 動作:
- プレイヤーとボタンUIの関連を見つけ、選択されたボタンに対して処理を実行します。
- 自動的に関連するプレイヤーUIと、選択されたボタンUIのインスタンスを取得します。
- もし選択されたボタンUIが見つかった場合、以下の処理を行います:
- もしボタンがクリックされた時にUIが削除される設定であれば、そのUIを削除します。
- ボタンUIが持つトリガーをアクティブ化し、プレイヤーに対してトリガーを発生させます。
- もし選択されたボタンUIが見つからなかった場合、エラーメッセージを表示します。
ActivateTrigger関数(ボタンUIのトリガーをアクティブ化し、プレイヤーにトリガーを発生させる関数)
- 目的:
- 指定されたボタンUIのトリガーをプレイヤーに対して発生させるための関数です。
- 動作:
- ボタンUIが持つトリガーをアクティブ化し、プレイヤーにトリガーを発生させます。
- トリガーの宛先を取得し、トリガーがインスティゲータを送信する設定であれば、トリガーを発生させる前にプレイヤーを指定して送信します。
- プレイヤーに対してトリガーを発生させます。
例えば、ボタンがジャンプボタンであれば、HandleSelectedUIButton関数は該当するボタンUIを見つけ、プレイヤーにジャンプのアクションを発生させることができます。

【逆にいうと】
ActivateTrigger
関数は、ボタンをクリックしたときに実際のアクションやイベントを発生させるための重要な役割を果たしています。この関数がなければ、ボタンをクリックしても何も起こらない状態となります。
HandleSelectedUIButton
関数は、ボタンが選択された際に実行される処理のエントリーポイントです。この関数内で、選択されたボタンUIに対して処理が行われます。
具体的には、ボタンUIが削除される設定であれば削除したり、ActivateTrigger
関数を呼び出してボタンに関連付けられたアクションやイベントを実行したりします。
ActivateTrigger
関数がボタンUIに関連付けられたアクションを発生させるために、ThisSignalDestination
という変数を使用しています。この変数には、ボタンUIが送信先となるシグナルの情報が格納されます。
そして、そのシグナルをトリガーとしてアクティブ化し、プレイヤーに対してイベントを発生させます。

要するに、ActivateTrigger
関数はボタンが押されたときに実際のアクションを起こすための役割を果たしているので、ボタンをクリックして何か面白いことや役立つことが起こるようになるわけですね!
buttonui := class():の詳細
クリックすると開きます。
# `buttonui`は具体的なクラス。
# ボタンUIの各種設定や状態管理を行うためのメソッドやプロパティが含まれています。
buttonui := class<concrete>():
@editable var ButtonText : string = ""
@editable var ButtonPosition : vector2 = vector2{}
@editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}
# 'ButtonStyle' key: {button_loud = 1, button_quiet = 2, button_regular = 3}.
@editable var ButtonStyle : buttonchoice_int = 3
@editable var RemovesUIOnClick : logic = true
# 終了後もボタンの状態を保存。例 ボタンを非表示にしてuiを終了し、uiを開いてもそのボタンは非表示のままです。
@editable SaveButtonState : logic = false
@editable ButtonSignal_Recieve : ButtonUI_UserOptions_Functions = ButtonUI_UserOptions_Functions{}
@editable ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
var SizeToContent : logic = false
var ButtonWidgetPerPlayer : [agent]widget = map{}
var EnabledStateMap : [agent]logic = map{}
var VisibleStateMap : [agent]logic = map{}
# ボタンUIを有効化
EnableWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetEnabled(true)
if(SaveButtonState?):
ValidAgent.SaveEnabledState(true)
# ボタンUIを無効化
DisableWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetEnabled(false)
if(SaveButtonState?):
ValidAgent.SaveEnabledState(false)
# ボタンの現在の有効状態を保存
(Agent : agent).SaveEnabledState(State : logic):void=
if(CurrentState := EnabledStateMap[Agent]):
if(set EnabledStateMap[Agent] = State){}
else:
set EnabledStateMap = ConcatenateMaps(EnabledStateMap, map{Agent => State})
# ボタンUIを表示
ShowWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetVisibility(widget_visibility.Visible)
if(SaveButtonState?):
ValidAgent.SaveVisibleState(true)
# ボタンUIを削除
HideWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetVisibility(widget_visibility.Collapsed)
if(SaveButtonState?):
ValidAgent.SaveVisibleState(false)
# ボタンの現在の可視状態を保存
(Agent : agent).SaveVisibleState(State : logic):void=
if(CurrentState := VisibleStateMap[Agent]):
if(set VisibleStateMap[Agent] = State){}
else:
set VisibleStateMap = ConcatenateMaps(VisibleStateMap, map{Agent => State})
このコードは、ボタンUIのクラスの定義です。
ButtonText
:- ボタンに表示するテキストを格納するプロパティです。
ButtonPosition
:- ボタンの位置を示すベクトル(2次元座標)を格納するプロパティです。
ButtonSize
:- ボタンのサイズを示すベクトル(2次元座標)を格納するプロパティです。
ButtonStyle
:- ボタンのスタイルを示す整数値で、1は loud、2は quiet、3は regular を表します。
RemovesUIOnClick
:- ボタンがクリックされた際にUIを非表示にするかどうかを示す論理値です。
SaveButtonState
:- ボタンの状態(有効/無効)を終了後も保存するかどうかを示す論理値です。
ButtonSignal_Recieve
:- ユーザーオプションを受け取るための関数を格納するプロパティです。
ButtonSignal_Send
:- ユーザーオプションを送信するためのイベントを格納するプロパティです。
SizeToContent
:- コンテンツに合わせてボタンのサイズを自動的に調整するかどうかを示す論理値です。
ButtonWidgetPerPlayer
:- 各プレイヤーごとのボタンウィジェットを格納するための辞書(マップ)です。
EnabledStateMap
:- 各プレイヤーごとの有効状態を記録するための辞書です。
VisibleStateMap
:- 各プレイヤーごとの表示状態を記録するための辞書です。
続いて、メソッドの解説です。
EnableWidget(Agent: ?agent):void
:- 指定されたプレイヤーのボタンUIを有効化するメソッドです。
Agent
には有効化する対象のプレイヤーを指定します。ButtonWidgetPerPlayer
から指定されたプレイヤーのボタンウィジェットを取得し、有効化します。SaveButtonState
が有効の場合、有効化された状態をEnabledStateMap
に保存します。
DisableWidget(Agent: ?agent):void
:- 指定されたプレイヤーのボタンUIを無効化するメソッドです。
Agent
には無効化する対象のプレイヤーを指定します。ButtonWidgetPerPlayer
から指定されたプレイヤーのボタンウィジェットを取得し、無効化します。SaveButtonState
が有効の場合、無効化された状態をEnabledStateMap
に保存します。
(Agent: agent).SaveEnabledState(State: logic):void
:- 指定されたプレイヤーのボタンの有効状態を保存するメソッドです。
Agent
には状態を保存するプレイヤーを指定し、State
には保存する有効状態(trueまたはfalse)を指定します。EnabledStateMap
から指定されたプレイヤーの現在の有効状態を取得し、それに応じて状態を更新します。
ShowWidget(Agent: ?agent):void
:- 指定されたプレイヤーのボタンUIを表示するメソッドです。
Agent
には表示する対象のプレイヤーを指定します。ButtonWidgetPerPlayer
から指定されたプレイヤーのボタンウィジェットを取得し、表示します。SaveButtonState
が有効の場合、表示された状態をVisibleStateMap
に保存します。
HideWidget(Agent: ?agent):void
:- 指定されたプレイヤーのボタンUIを非表示にするメソッドです。
Agent
には非表示にする対象のプレイヤーを指定します。ButtonWidgetPerPlayer
から指定されたプレイヤーのボタンウィジェットを取得し、非表示にします。SaveButtonState
が有効の場合、非表示にされた状態をVisibleStateMap
に保存します。
(Agent: agent).SaveVisibleState(State: logic):void
:- 指定されたプレイヤーのボタンの表示状態を保存するメソッドです。
Agent
には状態を保存するプレイヤーを指定し、State
には保存する表示状態(trueまたはfalse)を指定します。VisibleStateMap
から指定されたプレイヤーの現在の表示状態を取得し、それに応じて状態を更新します。
クラスは特定の機能を提供するためのコードのまとまりであり、プログラム内で再利用することができます。
このクラスを使って、ボタンのテキストや位置、スタイルを設定し、プレイヤーごとのボタンの状態と表示を制御することができます。
ボタンUIクラスの定義について
クリックすると開きます。
# ボタンUIのクラスを定義します。
buttonui := class<concrete>():
# ボタンのテキストを編集可能なプロパティとして定義します。
@editable var ButtonText : string = ""
# ボタンの位置を編集可能なプロパティとして定義します。ベクトル2(2次元ベクトル)を使用します。
@editable var ButtonPosition : vector2 = vector2{}
# ボタンのサイズを編集可能なプロパティとして定義します。ベクトル2を使用し、幅と高さを指定します。
@editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}
# ボタンのスタイルを編集可能なプロパティとして定義します。buttonchoice_int型を使用し、異なるスタイルのキーを指定できます。
# 'ButtonStyle' key: {button_loud = 1, button_quiet = 2, button_regular = 3}.
@editable var ButtonStyle : buttonchoice_int = 3
# クリック時にUIを非表示にするかどうかを編集可能なプロパティとして定義します。
@editable var RemovesUIOnClick : logic = true
# ボタンの状態を終了後も保存するかどうかを編集可能なプロパティとして定義します。
# 例: ボタンを非表示にしてUIを終了し、UIを開いてもそのボタンは非表示のままです。
@editable SaveButtonState : logic = false
# ボタンがユーザーオプションを受信するための関数を編集可能なプロパティとして定義します。
@editable ButtonSignal_Recieve : ButtonUI_UserOptions_Functions = ButtonUI_UserOptions_Functions{}
# ボタンがユーザーオプションを送信するためのイベントを編集可能なプロパティとして定義します。
@editable ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
# コンテンツに合わせてサイズを調整するかどうかを定義します。
var SizeToContent : logic = false
# 各プレイヤーごとにボタンウィジェットを格納する辞書を定義します。
var ButtonWidgetPerPlayer : [agent]widget = map{}
# 各プレイヤーごとに有効な状態を記録する辞書を定義します。
var EnabledStateMap : [agent]logic = map{}
# 各プレイヤーごとに表示されるかどうかを記録する辞書を定義します。
var VisibleStateMap : [agent]logic = map{}
このコードは、ボタンUIのクラスを定義しています。
まず、buttonui := class<concrete>()
は、buttonui
という名前のクラスを宣言しています。
その後、@editable
を使ってプロパティを定義しています。
プロパティは、ボタンのテキスト(ButtonText
)、位置(ButtonPosition
)、サイズ(ButtonSize
)、スタイル(ButtonStyle
)、クリック時にUIを非表示にするかどうか(RemovesUIOnClick
)、ボタンの状態を保存するかどうか(SaveButtonState
)、ユーザーオプションを受信するための関数(ButtonSignal_Recieve
)、ユーザーオプションを送信するためのイベント(ButtonSignal_Send
)を表しています。
その後、var
を使って変数を定義しています。SizeToContent
は、コンテンツに合わせてサイズを調整するかどうかを示す論理値です。
ButtonWidgetPerPlayer
は、各プレイヤーごとにボタンウィジェットを格納するための辞書(マップ)です。
EnabledStateMap
は、各プレイヤーごとに有効な状態を記録するための辞書です。VisibleStateMap
は、各プレイヤーごとに表示されるかどうかを記録するための辞書です。
このクラスは、ボタンUIの機能を提供するための設定とデータを保持します。
プログラムにおいてボタンUIを作成する際に、このクラスを使用してボタンのテキストや位置、スタイルなどを指定し、各プレイヤーごとに有効な状態や表示されるかどうかを管理することができます。

concrete指定子とは
クリックすると開きます。
「concrete」指定子がある場合、クラスは必ずデフォルト値を持つフィールドを持たなければなりません。
例えば、以下の例を見てみましょう。
class1 := class<concrete>:
Property : int = 0
# エラー: プロパティが初期化されていません
class2 := class<concrete>:
Property : int
# エラー: class3 は class1 の派生形なので <concrete> 指定子が必要です。
class3 := class(class1):
Property : int = 0
class1
では、Property
という整数型のフィールドが0で初期化されています。
このような初期値を持つフィールドが必要です。
しかし、class2
では、Property
に初期値が指定されていません。そのため、エラーが発生します。
クラスには初期値を持つフィールドが必須であるためです。
また、class3
はclass1
の派生クラスであり、Property
に初期値が指定されています。しかし、class3
自体が「concrete」という指定子を持っていないためエラーとなります。クラスが派生クラスである場合でも、「concrete」指定子が必要です。
「concrete」クラスが「abstract」クラスを直接継承できるのは、同じモジュールに両方のクラスが定義されている場合だけです。
しかし、concreteクラスが他のモジュールのconcreteクラスを直接継承することがあり、その2番目のconcreteクラスがそのモジュールのabstractクラスを直接継承することもあります。
【具体的に言うと】
「concrete」という言葉は、実際の物やもののことを意味します。例えば、本物のおもちゃのクマや犬、コンクリートで作られた道路や建物などが「concrete」です。
プログラミングの世界でも、「concrete」という言葉を使います。クラスというものは、プログラムで使う設計図のようなもので、実際の物やものを作るために使います。
それで、「concrete」指定子があるクラスは、本物の物やものを作るための設計図だと思ってください。
「concrete」指定子を持つクラスは、必ずデフォルトの値があるフィールド(特徴や情報)を持たなければなりません。
例えば、おもちゃのクマの設計図なら、そのクマの色やサイズなどのデフォルトの値が必要です。
しかし、クラスにはデフォルトの値を持つフィールドがないと、エラーが出ます。
つまり、おもちゃのクマの設計図にクマの色やサイズが書いていないと、おもちゃのクマを作ることができません。
また、もしクラスが他のクラスに派生(より具体的なものとして作成)される場合でも、その派生クラスも「concrete」である必要があります。つまり、もしクラス1の設計図からクラス2を作るなら、クラス2もデフォルトの値を持つ必要があります。
ただし、同じく「concrete」のクラスと「abstract」(抽象的な)なクラスは、同じ場所で定義されている場合にだけ、直接継承(設計図を基にして新しい設計図を作ること)ができます。
でも、別の場所で定義された別の「concrete」クラスからも継承することができます。
そして、その2番目の「concrete」クラスは、元の場所で定義された「abstract」クラスを継承することができます。
「concrete」は、実際の物やものを作るためのクラスの設計図に必要なデフォルトの値があることを意味します。

【さらに噛み砕くと】
「」という指定子は、クラスが実際の物やものを作るための設計図であることを示しています。「buttonui」クラスは、ボタンのユーザーインターフェース(UI)を作成し、設定や状態管理を行うためのメソッドやプロパティを含んでいます。
例えば、ボタンのテキストや位置、サイズなどの設定を変更できます。また、ボタンのスタイルやクリック時の動作なども設定できます。
そして、「buttonui」クラスは、実際のボタンの状態を保存するかどうかも設定できます。
例えば、ボタンを非表示にしてUIを閉じた後でも、再度UIを開いた時にボタンの状態が保存されているかどうかを選ぶことができます。
また、このクラスではボタンの表示や無効化、状態の保存などのメソッドも定義されています。
これらのメソッドを使うことで、ボタンの動作や表示を制御することができます。
「」指定子を使うことで、「buttonui」クラスが実際のボタンUIを作成するための設計図であることが明確になります。
これにより、クラス内に必要なプロパティやメソッドが正しく定義されていることが保証されます。
「」指定子は少し専門的な言葉かもしれませんが、実際の物やものを作るためのクラスであることを理解しておくと、このコードの役割を把握しやすくなるでしょう。

@editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}を小数点で入力している理由
クリックすると開きます。
vector2は、2次元のベクトルを表すためのデータ構造です。ベクトルとは、座標系内の位置や方向を表現するために使われるもので、数学的な概念です。
vector2は、XとYという2つの浮動小数点数(float)の成分を持ちます。X成分はベクトルの水平(横)方向の値を示し、Y成分は垂直(縦)方向の値を示します。
たとえば、(3.0, 2.5)というvector2は、X成分が3.0でY成分が2.5になります。
このベクトルは、平面上の点を表現することができます。
X成分が3.0なので、点は水平方向に3.0の位置にあります。
同様に、Y成分が2.5なので、点は垂直方向に2.5の位置にあります。
ベクトルを使うと、例えばゲーム開発でキャラクターの移動やオブジェクトの位置計算など、さまざまな処理が行えます。
vector2はそのような処理で頻繁に使用される基本的なデータ構造の一つです。
簡単にいうと、vector2構造体を使うことで、XとYの値をいじくることができます。

buttonchoice_intの詳細
クリックすると開きます。
@editable var ButtonStyle : buttonchoice_int = 3
# ボタンスタイルの選択を現在の3つにロック: {button_loud = 1, button_quiet = 2, button_regular = 3}.
buttonchoice_int := type{_X : int where 1 <= _X, 3 >= _X}
このコードは、ボタンのスタイルを選択するための設定を行っています。具体的には、ButtonStyleという変数を宣言し、その初期値を3に設定しています。
ButtonStyleは、buttonchoice_intという型を持っており、この型は1から3までの値しか受け付けません。
つまり、ButtonStyleの値は1、2、または3のいずれかである必要があります。
変数ButtonStyleの値を3にロックすることで、プログラム中で他の値に変更されないようにしています。
button_loud、button_quiet、button_regularといった異なるボタンスタイルがあるようですが、現在はbutton_regular(3)のスタイルが選択されていることを示しています。
このコードは、プログラミング言語における変数の宣言と初期化、また特定の範囲内での値の制限を設ける仕組みなどを利用して、ボタンスタイルの設定を行っているものです。
プログラミング初心者の方にとっては、変数とは値を保持するための箱のようなものであり、ここでは特定の範囲内での値の制限が行われることを理解しておくと良いでしょう。

@editable var RemovesUIOnClick :&@editable SaveButtonStateの詳細
クリックすると開きます。
@editable var RemovesUIOnClick : logic = true
# 終了後もボタンの状態を保存。例 ボタンを非表示にしてuiを終了し、uiを開いてもそのボタンは非表示のままです。
@editable SaveButtonState : logic = false
このコードは、ボタンの動作に関する設定を行っています。
最初の行では、RemovesUIOnClickという変数を宣言し、その初期値をtrueに設定しています。その後注釈が付いていますが、この設定によって、ボタンをクリックした後にUIを終了させるかどうかを制御しています。
もしRemovesUIOnClickがtrueの場合、ボタンをクリックするとUIが終了されます。
2番目の行では、「SaveButtonState」という変数を宣言し、その初期値をfalseに設定しています。この設定によって、ボタンの状態を終了後も保存するかどうかを制御しています。
もしSaveButtonStateがtrueの場合、ボタンを非表示にしてUIを終了させた後でも、次にUIを開いた際にそのボタンの状態(非表示かどうか)が保存されたままになります。
これらの設定は、UI(ユーザーインターフェース)の動作を制御するために使用されます。プログラムを実行すると、ユーザーがボタンをクリックした際の挙動や、UIの表示状態の永続性などを設定することができます。
前者はボタンをクリックしたらUIを終了させるかどうかの設定で、後者はボタンの状態を終了後も保存するかどうかの設定です。

@editable ButtonSignal_Recieve&@editable ButtonSignal_Sendの詳細
クリックすると開きます。
@editable ButtonSignal_Recieve : ButtonUI_UserOptions_Functions = ButtonUI_UserOptions_Functions{}
@editable ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
# UIボタンの機能とトリガーを管理するためのクラス
ButtonUI_UserOptions_Functions := class<concrete>():
# このuiボタンを有効にするトリガー
@editable EnableButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを無効にするトリガー
@editable DisableButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを表示するトリガー
@editable ShowButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを非表示にするトリガー
@editable HideButtonOnTrigger : trigger_device = trigger_device{}
# UIボタンのアクティブ化トリガーや実行者の送信設定を管理するためのクラス。
ButtonUI_UserOptions_Events := class<concrete>():
# アクティブ化するトリガー/送信先
@editable TriggerToActivate : trigger_device = trigger_device{}
# UIボタンの実行者を送信しますか?
#「instigator」は「実行者」という意味で、UIボタンを押したユーザーを意味します。
@editable SendInstigator : logic = true
ButtonSignal_Recieve
と ButtonSignal_Send
は、それぞれ ButtonUI_UserOptions_Functions
と ButtonUI_UserOptions_Events
クラスのインスタンスを表しています。
以下に、コードを徹底解説します。
@editable ButtonSignal_Recieve : ButtonUI_UserOptions_Functions = ButtonUI_UserOptions_Functions{}
ButtonSignal_Recieve
という名前の変数を宣言しています。@editable
で編集可能であることが示されています。
- データ型は
ButtonUI_UserOptions_Functions
で、初期値はButtonUI_UserOptions_Functions{}
です。- つまり、
ButtonUI_UserOptions_Functions
クラスのインスタンスを初期化しています。
- つまり、
@editable ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
ButtonSignal_Send
という名前の変数を宣言しています。- 同じく
@editable
で編集可能であることが示されています。
- 同じく
- データ型は
ButtonUI_UserOptions_Events
で、初期値はButtonUI_UserOptions_Events{}
です。- つまり、
ButtonUI_UserOptions_Events
クラスのインスタンスを初期化しています。
- つまり、
これらの変数は、UIボタンの機能とトリガーを管理するためのクラスのインスタンスを格納します。
ButtonSignal_Recieve
には ButtonUI_UserOptions_Functions
クラスのインスタンスが、ButtonSignal_Send
には ButtonUI_UserOptions_Events
クラスのインスタンスが代入されます。
ButtonSignal_Recieve
と ButtonSignal_Send
は、UIボタンの機能とトリガーを管理するためのクラスのインスタンスです。
ButtonSignal_Recieve
には ButtonUI_UserOptions_Functions
クラスのインスタンスが割り当てられ、ButtonSignal_Send
には ButtonUI_UserOptions_Events
クラスのインスタンスが割り当てられます。
これにより、UIボタンの具体的な動作やトリガーの設定を制御するためのオブジェクトが作成される感じですね。

ButtonUI_UserOptions_Functions := class<concrete>():の詳細
クリックすると開きます。
# UIボタンの機能とトリガーを管理するためのクラス
ButtonUI_UserOptions_Functions := class<concrete>():
# このuiボタンを有効にするトリガー
@editable EnableButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを無効にするトリガー
@editable DisableButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを表示するトリガー
@editable ShowButtonOnTrigger : trigger_device = trigger_device{}
# このuiボタンを非表示にするトリガー
@editable HideButtonOnTrigger : trigger_device = trigger_device{}
このコードは、UIボタンの機能とトリガーを管理するためのクラスであり、UIボタンの設定と操作に関する情報を保持します。
クラス名は「ButtonUI_UserOptions_Functions」で、以下の機能とトリガーを管理します。
- EnableButtonOnTrigger:
- このUIボタンを有効にするためのトリガーを指定します。
- 具体的にどのようなトリガーを使用するかは、このコードの他の部分に依存します。
- このトリガーが発生すると、UIボタンが有効になります(クリック可能になるなど)。
- DisableButtonOnTrigger:
- このUIボタンを無効にするためのトリガーを指定します。
- 同様に、具体的なトリガーは他の部分で設定されます。
- このトリガーが発生すると、UIボタンが無効化されます(クリックできないなど)。
- ShowButtonOnTrigger:
- このUIボタンを表示するためのトリガーを指定します。
- 具体的なトリガーは他のコードで定義されます。
- このトリガーが発生すると、UIボタンが表示されます。
- HideButtonOnTrigger:
- このUIボタンを非表示にするためのトリガーを指定します。
- 同様に、具体的なトリガーは他の部分で指定されます。
- このトリガーが発生すると、UIボタンが非表示にされます。
以上がこのクラスの主な機能です。このクラスはユーザーインターフェースにおけるボタンの動作や表示/非表示の制御に使用されます。
わかりやすく説明すると、このコードは「ButtonUI_UserOptions_Functions」というクラスを定義しています。このクラスは、UIボタンの機能とトリガーを管理するためのもので、有効化、無効化、表示、非表示などの操作を行うトリガーを指定することができます。
たとえば、特定のイベントが発生した際にボタンを有効にしたり、非表示にしたりするといったことが可能です。
これによって、ユーザーがボタンと対話する際の挙動や表示を制御することができます。

ButtonUI_UserOptions_Functions := class<concrete>():の詳細
クリックすると開きます。
# UIボタンのアクティブ化トリガーや実行者の送信設定を管理するためのクラス。
ButtonUI_UserOptions_Events := class<concrete>():
# アクティブ化するトリガー/送信先
@editable TriggerToActivate : trigger_device = trigger_device{}
# UIボタンの実行者を送信しますか?
#「instigator」は「実行者」という意味で、UIボタンを押したユーザーを意味します。
@editable SendInstigator : logic = true
このコードは、UIボタンのアクティブ化トリガーと実行者の送信設定を管理するためのクラスを示しています。
コードの詳細は以下のとおり。
ButtonUI_UserOptions_Events := class<concrete>():
ButtonUI_UserOptions_Events
というクラスを宣言しています。class<concrete>()
の部分は、このクラスが具象クラス(実際にインスタンス化できるクラス)であることを表しています。
@editable TriggerToActivate : trigger_device = trigger_device{}
TriggerToActivate
という名前の変数を宣言しています。@editable
は注釈と呼ばれ、この変数が編集可能であることを示しています。
trigger_device
というデータ型を持ち、初期値はtrigger_device{}
となっています。- この変数はアクティブ化するためのトリガーデバイスを表します。
@editable SendInstigator : logic = true
SendInstigator
という名前の変数を宣言しています。- また、
@editable
で編集可能であることが示されています。
- また、
- データ型は
logic
(真偽値)で、初期値はtrue
です。- この変数は、UIボタンの実行者(ユーザー)を送信するかどうかを制御します。
このクラスは、UIボタンのアクティブ化トリガー(TriggerToActivate
)と実行者の送信設定(SendInstigator
)を管理します。
アクティブ化トリガーは、ボタンをアクティブ化するためのデバイスを指定します。
SendInstigator
が true
の場合、UIボタンの実行者(ユーザー)情報が送信されます。
このクラスは、UIボタンを制御する際に、ボタンのアクティブ化条件(トリガー)を指定し、またユーザー情報を送信するかどうかを設定できる柔軟性を提供します。
このクラスはUIボタンに関する設定をまとめたもので、ボタンをアクティブ化するためのトリガーや実行者情報の送信設定を管理します。
具体的なデバイスをトリガーに設定することで、ボタンが押されたときにアクティブになるように制御できます。
また、SendInstigatorをtrueに設定することで、ボタンの実行者情報を送信することも可能です。

@editable SendInstigator : logic = trueの詳細
クリックすると開きます。
@editable SendInstigator : logic = true
このコードは、UIボタンの実行者(ユーザー)を送信するかどうかを設定するためのコードです。
SendInstigator
という変数を宣言し、その初期値をtrue
に設定しています。この変数は、UIボタンを押したユーザー(実行者)を送信するかどうかを制御します。
この変数は、注釈でinstigator
が実行者
を意味することが記載されています。つまり、UIボタンの実行者を指します。
もしSendInstigator
がtrue
の場合、UIボタンが押されたときに、実行者(ユーザー)が送信されます。
これによって、ボタンのアクションや操作に対して、どのユーザーが実行したのかを特定することができます。
要するに、このコードは「SendInstigator」という変数を使って、UIボタンの実行者(ユーザー)を送信するかどうかを設定しています。
もし設定がtrue
であれば、ボタンが押されたときに実行者情報が送信されます。
これによって、ボタンを押したユーザーを判別したり、その情報を使って他の処理を行ったりすることができます。

FindButtonUI関数とSendInstigator変数の目的と違い
クリックすると開きます。
FindButtonUI関数とSendInstigator変数のコードは、異なる目的を持っています。
FindButtonUI関数:
- 目的:
- 指定されたエージェントに関連付けられたボタンUIを検索して返す。
- 詳細:
- 関数の引数には、エージェント(プレイヤー)とウィジェット(ボタン)が指定されます。
- 関数は、指定されたエージェントに関連付けられたボタンUIを1つずつチェックします。
- チェック中のボタンUIに対応するウィジェットが存在するか確認し、一致する場合はそのボタンUIを返します。
- ウィジェットが見つからなかった場合は、falseを返します。
- 利用例:
- ゲームのUIにおいて、特定のプレイヤーに関連付けられたボタンを探すために使用されます。
SendInstigator変数:
- 目的:
- UIボタンの実行者(ユーザー)を送信するかどうかを設定する。
- 詳細:
- SendInstigatorという変数を宣言し、初期値をtrueに設定します。
- この変数は、UIボタンを押したユーザー(実行者)を送信するかどうかを制御します。
- もしSendInstigatorがtrueなら、ボタンが押されたときに実行者情報が送信されます。
- 利用例:
- ゲームやアプリケーションで、ボタンを押したユーザーを特定するために使用されます。
- 実行者情報を活用して、適切な処理や反応を行うことができます。
つまり、FindButtonUI関数は特定のエージェントに関連付けられたボタンを探し、それを返すための機能です。
一方、SendInstigator変数はUIボタンの実行者(ユーザー)を送信するかどうかを制御するためのものです。
FindButtonUI関数はボタンの特定や操作を補助し、SendInstigator変数は実行者の情報を管理することができます。

var SizeToContent : logic = falseの詳細
クリックすると開きます。
var SizeToContent : logic = false
SizeToContent
という名前の変数を宣言しています。- データ型は
logic
で、真偽値(true
またはfalse
)を表します。 - 初期値は
false
です。
これは、SizeToContent
という変数があり、その値が false
(偽)であることを表しています。
SizeToContent
という変数は、サイズをコンテンツに合わせるかどうかを制御するためのものです。
false
の場合は、サイズはコンテンツに合わせず、他の方法でサイズが決まることを意味します。
例えば、固定の幅や高さを指定することがあります。


自動でサイズを変更するか否かってことですね🌸
var ButtonWidgetPerPlayer : [agent]widget = map{}の詳細
クリックすると開きます。
var ButtonWidgetPerPlayer : [agent]widget = map{}
ButtonWidgetPerPlayer
という名前の変数を宣言しています。- データ型は
[agent]widget
で、エージェント(プレイヤー)ごとにウィジェット(UI要素)を格納するための配列(リスト)です。 - 初期値は
map{}
で、空のマップ(データを格納するコンテナ)です。
つまり、ButtonWidgetPerPlayer
は、エージェント(プレイヤー)ごとにウィジェットを管理するためのデータ構造です。
各エージェントに割り当てられたウィジェットがリストに格納されます。
ButtonWidgetPerPlayer
という変数は、エージェント(プレイヤー)ごとにウィジェット(UI要素)を格納するためのリストです。
最初の状態では、まだエージェントごとのウィジェットが格納されていないので、空のリストが作成されます。

var EnabledStateMap&var VisibleStateMapの詳細
クリックすると開きます。
var EnabledStateMap : [agent]logic = map{}
var VisibleStateMap : [agent]logic = map{}
このコードは、2つの変数 EnabledStateMap
と VisibleStateMap
を定義しています。それぞれは [agent]logic
というデータ型を持ち、map{}
という空のマップに初期化されています。
まず、[agent]logic
は、エージェントやプレイヤーごとに有効状態(EnabledStateMap)や表示状態(VisibleStateMap)を管理するためのデータ型です。
このデータ型は、エージェントやプレイヤーをキーとして、それぞれのエージェントに対応する有効状態や表示状態の論理値(真偽値)を格納します。
次に、map{}
は、空のマップデータ構造を初期化するための記法です。このマップは、キーと値の組み合わせでデータを保持します。ここでは、エージェントやプレイヤーをキーとし、それぞれのエージェントに対応するデフォルトの有効状態と表示状態を初期値として持つ空のマップを作成しています。
一般的な使い方としては、エージェントやプレイヤーが存在し、それぞれに対して有効状態や表示状態を管理したい場合に、EnabledStateMap
や VisibleStateMap
を使用します。
エージェントごとにマップを更新することで、特定のエージェントが有効(Enabled)または表示(Visible)されているかどうかを追跡することができます。
まとめ
今回はUIボタンのVerse(5)について解説しました。
最後に、完全なスクリプトを再掲しておきます↓
完全なスクリプトクリックすると開きます。
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
# Locks the choice of button styles to the current three: {button_loud = 1, button_quiet = 2, button_regular = 3}
buttonchoice_int := type{_X : int where 1 <= _X, 3 >= _X}
menumanagerdevice := class(creative_device):
# The trigger that will open up this ui menu
@editable TriggerToShowUI : trigger_device = trigger_device{}
# An array of button ui, configurable via the editor
@editable var ButtonUI : []buttonui = array{}
var MaybeMyUIPerPlayer : [player]?canvas = map{}
StringToMessage<localizes>(String : string):message = "{String}"
OnBegin<override>()<suspends>:void=
InitButtonFunctions()
TriggerToShowUI.TriggeredEvent.Subscribe(OpenUI)
OpenUI(Agent : ?agent):void=
if(ValidAgent := Agent?, Player := player[ValidAgent], PlayerUI := GetPlayerUI[Player]):
if(MyUI := MaybeMyUIPerPlayer[Player]?):
PlayerUI.RemoveWidget(MyUI)
if(set MaybeMyUIPerPlayer[Player] = false) {}
else:
NewUI := CreateMyUI(ValidAgent)
PlayerUI.AddWidget(NewUI, player_ui_slot{InputMode := ui_input_mode.All})
if(set MaybeMyUIPerPlayer[Player] = option{NewUI}) {}
CreateMyUI(Agent : agent) : canvas =
for(CurrButtonUI : ButtonUI):
case(CurrButtonUI.ButtonStyle):
1 =>
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
2 =>
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
3 =>
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
_ =>
Print("~ERROR: ButtonStyle integer over/under-flow")
CanvasArray := ReturnCanvasSlots(Agent)
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
return MyInteractableButtons
ReturnCanvasSlots(Agent : agent):[]canvas_slot=
var CanvasSlotArray : []canvas_slot = array{}
for(ThisButtonUI : ButtonUI):
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
Agent.LoadButtonState(ThisButtonUI)
ThisSlot := canvas_slot:
Offsets := margin{Top := ThisButtonUI.ButtonPosition.Y, Left := ThisButtonUI.ButtonPosition.X, Bottom := ThisButtonUI.ButtonSize.Y, Right := ThisButtonUI.ButtonSize.X}
ZOrder := 0
SizeToContent := ThisButtonUI.SizeToContent
Widget := ThisWidget
set CanvasSlotArray += array{ThisSlot}
return CanvasSlotArray
DeleteUI(Message : widget_message) : void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
PlayerUI.RemoveWidget(MyUI)
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
HandleSelectedUIButton(Message : widget_message):void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
ThisWidget := Message.Source
StaleButtonUI := Player.FindButtonUI(ThisWidget)
if(ThisButtonUI := StaleButtonUI?):
if(ThisButtonUI.RemovesUIOnClick?):
DeleteUI(Message)
ThisButtonUI.ActivateTrigger(Player)
else:
Print("~ERROR: No buttonui found!")
(Agent : agent).FindButtonUI(ThisWidget : widget):?buttonui=
for(ThisButtonUI : ButtonUI):
if(StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if(ThisWidget = StaleWidget):
return option{ThisButtonUI}
return false
(ThisButtonUI : buttonui).ActivateTrigger(Player : player):void=
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
if(ThisSignalDestination.SendInstigator?):
ThisSignalDestination.TriggerToActivate.Trigger(Player)
ThisSignalDestination.TriggerToActivate.Trigger()
# Loads all button states that have 'SaveButtonState' turned on
(Agent : agent).LoadButtonState(ThisButtonUI : buttonui):void=
if(ThisButtonUI.SaveButtonState?):
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if(ThisEnabledState := ThisButtonUI.EnabledStateMap[Agent]):
ThisWidget.SetEnabled(ThisEnabledState)
if(ThisVisibleState := ThisButtonUI.VisibleStateMap[Agent]):
case(ThisVisibleState):
true => ThisWidget.SetVisibility(widget_visibility.Visible)
false => ThisWidget.SetVisibility(widget_visibility.Collapsed)
_ => Print("~ERROR: Failed to fetch 'ThisVisibleState")
else:
Print("~ERROR: Failed to fetch widget!")
# Initializes the 'functions' tab for each button ui
InitButtonFunctions():void=
for(ThisButtonUI : ButtonUI):
ThisButtonUI.ButtonSignal_Recieve.EnableButtonOnTrigger.TriggeredEvent.Subscribe(ThisButtonUI.EnableWidget)
ThisButtonUI.ButtonSignal_Recieve.DisableButtonOnTrigger.TriggeredEvent.Subscribe(ThisButtonUI.DisableWidget)
ThisButtonUI.ButtonSignal_Recieve.ShowButtonOnTrigger.TriggeredEvent.Subscribe(ThisButtonUI.ShowWidget)
ThisButtonUI.ButtonSignal_Recieve.HideButtonOnTrigger.TriggeredEvent.Subscribe(ThisButtonUI.HideWidget)
buttonui := class<concrete>():
@editable var ButtonText : string = ""
@editable var ButtonPosition : vector2 = vector2{}
@editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}
# 'ButtonStyle' key: {button_loud = 1, button_quiet = 2, button_regular = 3}
@editable var ButtonStyle : buttonchoice_int = 3
@editable var RemovesUIOnClick : logic = true
# Saves the state the button is in even after exiting. Example: Hiding a button, exiting the ui, and then opening the ui will still have that button hidden
@editable SaveButtonState : logic = false
@editable ButtonSignal_Recieve : ButtonUI_UserOptions_Functions = ButtonUI_UserOptions_Functions{}
@editable ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
var SizeToContent : logic = false
var ButtonWidgetPerPlayer : [agent]widget = map{}
var EnabledStateMap : [agent]logic = map{}
var VisibleStateMap : [agent]logic = map{}
EnableWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetEnabled(true)
if(SaveButtonState?):
ValidAgent.SaveEnabledState(true)
# Fades the button ui
DisableWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetEnabled(false)
if(SaveButtonState?):
ValidAgent.SaveEnabledState(false)
# Saves the enabled state the button is currently in
(Agent : agent).SaveEnabledState(State : logic):void=
if(CurrentState := EnabledStateMap[Agent]):
if(set EnabledStateMap[Agent] = State){}
else:
set EnabledStateMap = ConcatenateMaps(EnabledStateMap, map{Agent => State})
ShowWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetVisibility(widget_visibility.Visible)
if(SaveButtonState?):
ValidAgent.SaveVisibleState(true)
# Completely removes the button ui
HideWidget(Agent : ?agent):void=
if(ValidAgent := Agent?, ThisButtonWidget := ButtonWidgetPerPlayer[ValidAgent]):
ThisButtonWidget.SetVisibility(widget_visibility.Collapsed)
if(SaveButtonState?):
ValidAgent.SaveVisibleState(false)
# Saves the visible state the button is currently in
(Agent : agent).SaveVisibleState(State : logic):void=
if(CurrentState := VisibleStateMap[Agent]):
if(set VisibleStateMap[Agent] = State){}
else:
set VisibleStateMap = ConcatenateMaps(VisibleStateMap, map{Agent => State})
ButtonUI_UserOptions_Functions := class<concrete>():
# The trigger that will enable this ui button, making it 'un-fade' and clickable
@editable EnableButtonOnTrigger : trigger_device = trigger_device{}
# The trigger that will disable this ui button, making it 'fade' and unclickable
@editable DisableButtonOnTrigger : trigger_device = trigger_device{}
# The trigger that will show this ui button, making it visible and clickable
@editable ShowButtonOnTrigger : trigger_device = trigger_device{}
# The trigger that will hide this ui button, making it not visible at all and therefore unclickable
@editable HideButtonOnTrigger : trigger_device = trigger_device{}
ButtonUI_UserOptions_Events := class<concrete>():
# The trigger/destination to activate
@editable TriggerToActivate : trigger_device = trigger_device{}
# Do we send the instigator of the UI button?
@editable SendInstigator : logic = true
お疲れさまでした!!!!
5ページ目まで本当にお疲れさまです🍵
はなまる💮
僕のTwitterアカウントです。