

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

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

もくじ
UIボタンの作り方(4ページ目)│Verse解説の続き
HandleSelectedUIButton(Message : widget_message):void=の詳細
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!")
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
このコードは、HandleSelectedUIButton
という関数を定義しています。この関数は、プレイヤーUIとボタンUIに関連する操作を処理します。
- 1行目: 関数の定義を行っています。関数名は
HandleSelectedUIButton
で、引数としてMessage
という型がwidget_message
のデータを受け取ります。戻り値の型はvoid
です。 - 3行目: コメント行です。「#」以降のテキストはプログラムとして実行されず、説明文として利用されます。
- 5行目:
if
文を使って条件式を評価しています。「:=」は代入演算子で、右辺の値を左辺に代入します。「GetPlayerUI[Message.Player]」は、Message.Player
に対応するプレイヤーUIを取得する関数を呼び出しています。 - 6行目:
,
を使って複数の条件式を結合しています。「MaybeMyUIPerPlayer[Message.Player]」は、Message.Player
に対応するボタンUIを取得する関数を呼び出しています。 - 8行目:
Player
変数にMessage.Player
の値を代入しています。 - 10行目:
ThisWidget
変数にMessage.Source
の値を代入しています。 - 12行目:
Player
オブジェクトのFindButtonUI
関数を呼び出し、ThisWidget
を引数として渡しています。 - 14行目:
ThisButtonUI
変数にStaleButtonUI
の値を代入しています。StaleButtonUI
が存在する場合、この行を実行します。 - 16行目:
ThisButtonUI
が存在する場合の処理に入ります。この行でRemovesUIOnClick
プロパティがTrue
かどうかをチェックしています。 - 18行目:
DeleteUI(Message)
を呼び出して、UIを削除します。 - 21行目:
ThisButtonUI
のActivateTrigger
関数を呼び出して、Player
を引数として渡します。 - 24行目:
ThisButtonUI
が存在しない場合、エラーメッセージを出力します。
このように、このコードはプレイヤーUIとボタンUIに関連する操作を処理するためのものです。


両者を関連付けているわけですね🌸
このコードの最大の目的は、「プレイヤーUIとボタンUIに関連する操作を処理する」ことです。
具体的には、以下の動作を行います:
GetPlayerUI
関数とMaybeMyUIPerPlayer
関数を使って、プレイヤーUIとボタンUIを取得します。- メッセージに含まれるプレイヤー情報を取得します。
- ウィジェットメッセージから現在のウィジェットを取得します。
- プレイヤーのボタンUIの中から、現在のウィジェットに関連するボタンUIを検索します。
- ボタンUIが存在する場合、そのボタンUIの設定に基づいて以下の処理を実行します:
- クリックされた際にUIを削除する設定がされている場合、UIを削除します。
- ボタンのトリガーをアクティベートします。
- ボタンUIが存在しない場合は、エラーメッセージを出力します。
つまり、このコードは特定のユーザーインターフェース(UI)要素で発生したイベント(ボタンのクリックなど)を処理し、それに応じて関連する操作を実行します。

プレイヤーUIとボタンUIの違い
クリックすると開きます。
両者の違いは以下のとおり。
- プレイヤーUI(PlayerUI): プレイヤーの全体的な情報や機能を提供するユーザーインターフェース(UI)です。
- 通常、ゲームやアプリケーション内で1つのプレイヤーに対して1つのプレイヤーUIが存在します。
- プレイヤーUIは、プレイヤーのステータス、アクションボタン、インベントリ、属性などの要素を表示・制御します。
- ボタンUI(ButtonUI): 特定のアクションをトリガーするために使用されるUI要素です。
- ボタンUIは通常、プレイヤーUI内の特定のセクションや特定のウィジェットに関連付けられ、プレイヤーがボタンをクリックすることでアクションが実行されます。
- ボタンUIは、プレイヤーがゲーム内のアクション(攻撃、ジャンプ、アイテム使用など)をトリガーするために使われることが一般的です。
したがって、プレイヤーUIはプレイヤー全体の情報や機能を提供し、複数の要素(ボタンなど)を含む場合があります。一方、ボタンUIは単一のアクションをトリガーするためのUI要素です。
多くの場合、プレイヤーUI内に存在し、プレイヤーUIの一部として機能します。

【例】
プレイヤーUIとボタンUIの関係性を身近なもので例えると、プレイヤーUIは「スマートフォンのホーム画面」であり、ボタンUIは「アプリケーションのアイコン」になります。
スマートフォンのホーム画面(プレイヤーUI)は、複数の要素を含んでいます。それぞれの要素は、ウィジェットやアプリケーションへのアクセスや情報の表示など、異なる機能を提供します。
例えば、時計や天気予報、メール、カレンダーなどのウィジェットがあります。これらはプレイヤー全体の情報や機能を提供するものです。
一方、アプリケーションのアイコン(ボタンUI)は、特定のアクション(アプリを起動するなど)をトリガーするためのものです。ホーム画面上のアイコンをタップすることで、対応するアプリケーションが起動されます。これは単一のアクションを実行するUI要素であり、プレイヤーUIの一部として機能しています。
このように、プレイヤーUIは複数の要素を含んでプレイヤー全体の情報や機能を提供し、ボタンUIは単一のアクションをトリガーするUI要素としてプレイヤーUIの一部となる関係性を持っています。
プレイヤーUIは画面上に表示されるUIの全体的な要素を指し、複数の要素(ボタン、ステータス表示、インベントリなど)を含みます。
一方、ボタンUIはプレイヤーUI内の個別のボタン要素であり、単一のアクションをトリガーするためのUIです。
まり、プレイヤーUIは画面に表示される全体的なUIを指し、ボタンUIはその中の個別のボタンのUIとなります。

widget_message構造体の詳細
クリックすると開きます。
widget_message structは、Unreal Engine(アンリアルエンジン)において、ウィジェットが発生させるイベントのためのパラメータを持つデータ構造体です。
以下は、structのメンバーの詳細です:
- Player(プレイヤー):
- イベントをトリガーしたプレイヤーを表す変数です。
- このメンバーはplayer型です。
- Source(ソース):
- イベントをトリガーしたウィジェットを表す変数です。
- このメンバーはwidget型です。
structは、関数やメソッドではなく、データだけを保持するためのものです。この場合、widget_message structは、ウィジェットがイベントを発生させる際に、そのイベントに関連するプレイヤーやウィジェットの情報を保持する役割を持っています。
このようなデータ構造体は、イベントに関連する情報をまとめるために使用されます。ウィジェット内でイベントが発生した際には、このstructのインスタンスが作成され、イベントのトリガー情報が格納されます。その後、このstructを引数として関数やメソッドに渡すことができ、イベントを処理する際に必要な情報を取得することができます。
わかりやすくいうとwidget_message構造体は、Unreal Engine(アンリアルエンジン)というゲーム開発用のプログラミングツールで使用されるデータ構造体です。
widget_message構造体は、ウィジェット(画面上に表示されるボタンやテキストなどの要素)が発生させるイベントに関連する情報を含んでいます。イベントとは、例えばボタンがクリックされたときやテキストが入力されたときなど、ユーザーの操作に応じてプログラムが反応することを指します。
このwidget_message構造体は、イベントが発生した際にプログラムに渡され、そのイベントに関連する情報を含んでいます。たとえば、どのプレイヤーがイベントをトリガーしたのかや、どのウィジェットがイベントを発生させたのかといった情報が含まれています。
この構造体を使うことで、プログラムはイベントに応じた処理を行うことができます。
たとえば、ボタンがクリックされたら何らかのアクションを実行する、テキストが入力されたらそれを取得して処理するなど、ユーザーの操作に合わせてゲームやアプリケーションの動作を制御することができます。
if (PlayerUI := Get~Message.Playerの詳細
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
この部分のコードは、PlayerUI
と MyUI
の情報を取得し、Player
という変数に Message
の Player
情報を格納しています。
PlayerUI
はGetPlayerUI[Message.Player]
の結果を代入しています。これは、Message.Player
に関連するプレイヤーUIの情報を取得するための処理です。GetPlayerUI
は関数や辞書などを使ってプレイヤーUIを探し、結果を返します。MyUI
はMaybeMyUIPerPlayer[Message.Player]?
の結果を代入しています。MaybeMyUIPerPlayer
は、可能性があるプレイヤーごとのUI情報を持つ辞書やリストなどのデータ構造を指します。MaybeMyUIPerPlayer[Message.Player]
の結果が存在する場合は、その情報をMyUI
に代入します。Player := Message.Player
は、Message.Player
の情報をPlayer
という変数に格納しています。これは、イベントをトリガーしたプレイヤーの情報を取得するための処理です。
このコードは、プレイヤーUIとMyUIの情報を取得し、関連付けるための処理を行っています。
プログラムの他の部分でこれらの変数が使用される場合、対応するUIにアクセスするための参照となります。
なお、:=
は条件付きの代入演算子であり、=
の代わりに使用されます。
この演算子は、値を代入すると同時に、代入された値自体を条件式の結果として返します。
これにより、変数への代入と条件判定を同時に行うことができます。

このコードの最大の目的は、特定のプレイヤーが特定のボタンを選択した場合に関連する操作や処理を実行することです。
具体的には以下のとおり。
Message
という引数には、ボタンが選択されたときに送信される情報が含まれています。GetPlayerUI
関数を使って、Message.Player
(ボタンを選択したプレイヤー)に関連するプレイヤーUI情報を取得します。MaybeMyUIPerPlayer
関数を使って、Message.Player
に関連する特別なUI情報(MyUI)を取得します。- もし
PlayerUI
とMyUI
の両方が存在する場合、以下の処理を実行します。 Message.Player
(ボタンを選択したプレイヤー)をPlayer
変数に代入します。Message.Source
(ボタンのウィジェット情報)をThisWidget
変数に代入します。Player
オブジェクトのFindButtonUI
メソッドを使用して、ThisWidget
に関連付けられたボタンUIの情報を検索します。- もしボタンUIが見つかった場合、以下の処理を実行します。
- もし
ThisButtonUI.RemovesUIOnClick
がtrue
の場合、ボタンがクリックされたときにUIを削除するためにDeleteUI
関数を呼び出します。 ThisButtonUI.ActivateTrigger(Player)
を実行して、ボタンのトリガーをアクティベートします。
- もしボタンUIが見つからなかった場合、
"~ERROR: No buttonui found!"
というエラーメッセージを出力します。
このコードは、特定のプレイヤーがボタンを選択したときに、関連するUI操作やトリガーのアクティベートなど特定の処理を行うためのものです。

PlayerUI := GetPlayerUI[Message.Player]の詳細
クリックすると開きます。
PlayerUI := GetPlayerUI[Message.Player]
は、指定されたプレーヤー(Message.Player
)に関連付けられたプレーヤーUI(User Interface)を取得するためのコードです。
プログラムの前提条件として、ゲームやインタラクティブなアプリケーションで、プレーヤーごとに独自のユーザーインターフェイスが存在する場合があります。
例えば、各プレーヤーがゲーム内のボタンやテキストエリアなどを持っているゲーム画面を考えてみましょう。
このコードでは、指定されたプレーヤーのユーザーインターフェイスを PlayerUI
という変数に格納することを意味しています。
GetPlayerUI
は、引数として指定されたプレーヤーを基準に、各プレーヤーに関連付けられたユーザーインターフェイスを検索・取得するための関数やメソッドの一部として使われるものです。
上記のコードは、指定されたプレーヤーに関連付けられたユーザーインターフェイスを取得し、PlayerUI
という変数に格納するという意味を持っています。以降のコードで、取得したユーザーインターフェイスに対して処理を行うことが予想されます。
PlayerUI := GetPlayerUI[Message.Player]
のコードは、GetPlayerUI
というマップ(または辞書)において、Message.Player
というキーに関連付けられた値を取得しています。

キーを指定してマップの要素にアクセスすることで、対応する値を取得することができます。この場合、Message.Player
をキーとした要素がマップ内に存在する場合、その値が PlayerUI
変数に代入されます。
PlayerUI 変数に代入される値は、Message.Player と関連があるプレイヤーのUIウィジェットやコンポーネントなどの情報です。
指定されたプレーヤー(Message.Player)の詳細
クリックすると開きます。
指定されたプレーヤー(Message.Player
)とは、プログラム内で明示的に指定された特定のプレーヤーを表す値です。プログラムやゲームのコンテキストによって異なりますが、一般的には以下のようなイメージで理解できます。
プログラムがゲームを実行している場合、ゲームには複数のプレーヤーが存在することが一般的です。それぞれのプレーヤーは、特定のユーザーが制御しているキャラクターやエージェントを表しています。プログラムは各プレーヤーを区別するために、識別子(ID)や名前、番号などの値を使用します。
Message.Player
は、プログラム内で受け取ったメッセージやイベントに関連付けられたプレーヤーを指す変数やプロパティです。
一般的な用途としては、特定のイベントやボタンのクリックなどのユーザーの操作に応じて、対応するプレーヤーに関連する処理を実行するために使用されます。
例えば、ボタンがクリックされたというイベントが発生した場合、Message.Player
の値はクリックしたプレーヤーを示します。この値を使用することで、そのプレーヤーに関連付けられた情報や操作を特定し、適切な処理を行うことができます。
要するに指定されたプレーヤーを特定するための情報を表す変数だと理解してください。
プレーヤーに固有のデータや処理を操作する際に利用される重要な要素です。

player
だけでもプレーヤーを表すことはできますが、Message.Player
のように Message
をつけることで、コード内のプレーヤーに関連する情報を持つメッセージやイベントを表現するための手段になります。
- メッセージのソースの明確化:
Message.Player
を使うことで、プレーヤーに関する情報が含まれているメッセージやイベントがどこから来たのかを明示的に示すことができます。- 他のプレーヤーや部分には影響を与えずに、特定のプレーヤーに対する操作や処理を行う際に利用されます。
- スケーラビリティの向上:
- ゲームやアプリケーションが複数のプレーヤーをサポートしている場合、
player
だけではどのプレーヤーを指しているのか特定できません。 - しかし、
Message.Player
を使うことで、プログラムのスケーラビリティが向上します。 - つまり、プレーヤーごとに異なる処理やデータを管理することができます。
- ゲームやアプリケーションが複数のプレーヤーをサポートしている場合、
- コードの可読性の向上:
Message.Player
を使うことで、コード内でのプレーヤーに関連する処理や情報へのアクセスが明確になります。- 誰がどのプレーヤーに対しての操作を行っているのかを把握しやすくなり、コードの可読性が向上します。
総じて言えば、Message.Player
のような表現は、プレーヤーに関するデータや処理をより明確かつ一貫して扱うための手段となります。


プレイヤーはプレイヤーでも、ボタンをクリックしたプレイヤーを指したいがために、「Message
」をつけているということですね🌸
【詳細】
Message.Player
を使う理由の一つは、特定のイベントやボタンのクリックなどのユーザーの操作に関連するプレーヤーを明示的に指定するためです。
ボタンをクリックした場合、そのイベントはプログラムによって受信されます。それに伴って、どのプレーヤーがそのボタンをクリックしたのかを特定する必要があります。
このような場合、Message.Player
を使用して、その情報をメッセージに含めることができます。
メッセージにプレーヤー情報を含めることで、プログラム内でそのプレーヤーに関連するデータや処理を特定できます。また、複数のプレーヤーが存在する場合でも、各プレーヤーが異なるボタンをクリックした場合でも、Message.Player
を使うことで適切な処理を行うことができます。
まとめると、Message.Player
を使うことで、特定のイベントや操作がどのプレーヤーに関連しているのかを明確にし、それに応じた処理を行うことができるのです。

GetPlayerUI関数の詳細
クリックすると開きます。
GetPlayerUI
関数は、与えられた Player
(プレーヤー)に関連付けられた player_ui
コンポーネントを取得するための関数です。Player
に関連付けられた player_ui
が存在しない場合は、関数は失敗します。
この関数は、「UEFNGetPlayerUI」という形式で示されていますが、これは関数の名前や存在を示すための表記方法です。
構文:
GetPlayerUI<Player: player>: player_ui
パラメータ:
Player
(player): 関連付けられたplayer_ui
コンポーネントを取得したいプレーヤーを指定します。
返り値:
player_ui
: プレーヤーに関連付けられたplayer_ui
コンポーネントが返されます。
例えば、あるゲームでプレーヤーが画面上でボタンをクリックすると、そのプレーヤーに関連づけられた player_ui
を操作する必要がある場合に、GetPlayerUI
関数を使用することができます。
この関数は、特定のプレーヤーに関する情報を取得し、そのプレーヤーの player_ui
コンポーネントを取得するために使用されます。
player_ui
クラスは、プレーヤーのUIにウィジェットを追加したり削除したりするためのメインインタフェースです。
以下に、player_ui
クラスの詳細を解説します。
メンバー:
このクラスには、関数のみが存在し、データメンバーはありません。
関数:
AddWidget
:- デフォルトの
player_ui_slot
の設定オプションを使用して、ウィジェットをplayer_ui
に追加します。
- デフォルトの
AddWidget
(オーバーロード):- 指定したスロット(
Slot
)を使用して、ウィジェットをplayer_ui
に追加します。 - スロットはウィジェットの配置や設定オプションを指定するために使用されます。
- 指定したスロット(
RemoveWidget
:- 指定したウィジェットを
player_ui
から削除します。
- 指定したウィジェットを
player_ui
クラスを使用すると、ゲーム内の特定のプレーヤーのUIにウィジェットを追加したり、削除したりすることができます。
たとえば、スコアボードやミニマップなど、プレーヤーに情報を表示するためのウィジェットを操作する場合に使用されます。
GetPlayerUI関数とplayer_uiクラスの関係性
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
GetPlayerUI
関数と player_ui
クラスは、プレーヤーのUIに関連した情報やウィジェットを取得したり操作したりするために使用される関数とクラスです。
まず、GetPlayerUI
関数について説明します。
この関数は、与えられた Player
(プレーヤー)に関連付けられた player_ui
コンポーネントを返します。つまり、特定のプレーヤーに関連付けられたUI要素を取得するために使用されます。
もし指定したプレーヤーに対応する player_ui
が存在しない場合は、関数は失敗します。
例えば、ゲーム中のプレーヤーごとに個別のスコアボードやミニマップを持たせたい場合に、GetPlayerUI
関数を使用して、それぞれのプレーヤーの player_ui
を取得することができます。
次に、player_ui
クラスについて説明します。このクラスは、プレーヤーのUIにウィジェットを追加したり削除したりするための主要なインターフェースです。
player_ui
クラスには、ウィジェットの追加や削除に関連するいくつかの関数があります。AddWidget
関数は、指定された設定オプションを使用してウィジェットを player_ui
に追加します。
AddWidget
関数は、さまざまな設定オプションを持つスロット(Slot
)を使用してウィジェットを player_ui
に追加するオーバーロードも提供しています。また、RemoveWidget
関数は、player_ui
から指定したウィジェットを削除します。
例えば、ゲーム中に特定のプレーヤーのスコア表示用のウィジェットを追加したり、削除したりする場合に、player_ui
クラスの関数を使用します。
【例】
ゲームのマルチプレーヤーモードで考えることができます。
各プレーヤーには個別のスコアボードが存在し、そのスコアボードにはプレーヤーの得点やランキングが表示されます。
この場合、GetPlayerUI
関数を使用して、各プレーヤーの player_ui
を取得し、player_ui
クラスの関数を使用してスコアボードのウィジェットを追加したり削除したりすることができます。
それぞれのプレーヤーは、自分自身に関連するUI要素を操作できるようになります。
つまり、GetPlayerUIはplayer_uiを取得するための関数といえます。

GetPlayerUI
関数を使用することで、特定のプレーヤーに関連付けられた player_ui
を取得することができます。
player_ui
はプレーヤーのUIに関連した情報やウィジェットを管理するためのクラスです。GetPlayerUI
関数を使用して player_ui
を取得した後、取得した player_ui
を介してUI要素を制御したり、ウィジェットを追加したり削除したりすることができます。

GetPlayerUI
関数は player_ui
を呼び出すための手段の一つと言えますね!
特定のプレーヤーに関連付けられた player_ui
を取得することで、その player_ui
上でUI要素やウィジェットの操作を行うことができます。

このコードでは、PlayerUI
はMessage.Player
に関連するすべてのプレイヤーUIを表しており、MyUI
はMessage.Player
の中で特定の条件または制約に基づいて関連付けられたプレイヤーごとのUIを表しています。
具体的には、GetPlayerUI[Message.Player]
は、Message.Player
に関連するすべてのプレイヤーUI情報を取得する関数(またはデータ構造)です。これにより、PlayerUI
にはすべてのプレイヤーのUI情報が関連付けられます。
一方、MaybeMyUIPerPlayer[Message.Player]
は、特定の条件や制約に合致するMessage.Player
のプレイヤーにのみ関連付けられたUI情報を表しています。MaybeMyUIPerPlayer
は、各プレイヤーをキーとして持ち、条件を満たす場合にそのプレイヤーに対応するUI情報を関連付けます。
ただし、条件を満たさないプレイヤーに対しては関連付けが行われないこともあります。
したがって、PlayerUI
はすべてのプレイヤーのUI情報を表し、MyUI
は条件を満たすプレイヤーごとのUI情報を表すと解釈できます。
if (PlayerUI := GetPlayerUI[Message.Player])で[]が採用されている理由
クリックすると開きます。
if (PlayerUI := GetPlayerUI[Message.Player])
で [Message.Player]
の形式が使用されている部分は、プログラミングにおいてインデックスやキーを使用して要素をアクセスするための記法です。
ここでは、GetPlayerUI
関数に Message.Player
を引数として渡し、返されたプレーヤーに関連付けられた player_ui
コンポーネントを PlayerUI
という変数に割り当てています。
この記法を使うことで、リストや辞書などのデータ構造に対して特定の要素を指定することができます。Message.Player
がプレーヤーの識別子やインデックスであり、GetPlayerUI
関数がそれを受け取って該当する player_ui
を返すという仕組みです。
具体的な例として、GetPlayerUI
関数がプレーヤーIDを引数として受け取り、それを利用してプレーヤーに関連付けられた player_ui
を返す場合を考えてみましょう。
Message.Player
が特定のプレーヤーのIDであるとすると、GetPlayerUI[Message.Player]
はそのIDを引数にして player_ui
を取得することを表しています。
このような記法を使うことで、データ構造内の特定の要素にアクセスし、それを変数に割り当てることができます。
また、条件文の中で同時に変数の割り当てと条件の評価を行うことができるため、コードを簡潔に記述することができますね。

(MyUI := MaybeMyUIPerPlayer[Message.Player]?):の詳細
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
(MyUI := MaybeMyUIPerPlayer[Message.Player]?)
の部分は、プレイヤーごとに関連付けられた MaybeMyUIPerPlayer
というマップ(または辞書)から、Message.Player
というキーに関連付けられた値を取得しています。この値は MyUI
変数に代入されます。
ここで使われている ?
はオプショナルチェイニング演算子(Optional Chaining Operator)と呼ばれるもので、マップからの値の取得において、キーが存在しない場合に例外エラーを回避するために使用されます。
具体的には、以下の手順で処理が行われます:
MaybeMyUIPerPlayer
マップから、キーMessage.Player
に関連付けられた値を取得しようとします。- もしキーが存在する場合(値が見つかった場合)、その値が
MyUI
変数に代入されます。 - もしキーが存在しない場合(値が見つからない場合)、
MyUI
変数には null や未定義の値が代入され、エラーは発生しません。
つまり、このコードは、プレイヤーごとに関連付けられた MaybeMyUIPerPlayer
マップから Message.Player
というキーに対応する値を取得し、もし存在すればそれを MyUI
変数に代入するという処理を行っています。キーが存在しない場合にエラーが発生せず、処理が続行されることが特徴です。
【例】
レストランでの顧客と注文の関係性を使った例えです:
あなたがレストランのオーナーで、お客さんがそれぞれのテーブルに座っています。GetPlayerUI
関数は、各テーブルのお客さんに対して「あなたの注文は何ですか?」と尋ね、各お客さんの注文情報を取得するとします。
それらの情報はPlayerUI
変数に保存されます。
さらに、特別なオーダーをすることができる「特別メニュー」があるとします。ただし、特別メニューはすべてのお客さんに対して用意されているわけではなく、注文することができるお客さんも限られています。
この特別メニューに相当するのがMaybeMyUIPerPlayer
です。MaybeMyUIPerPlayer
から特定のお客さんの情報を取得することで、そのお客さんが特別メニューを注文できるかどうかを確認します。
取得した情報はMyUI
変数に保存されます。
最後に、Player
はメモ用紙で、現在の注文を記録しています。Message.Player
をPlayer
に代入することで、メモ用紙に現在のお客さんの名前を書き込みます。
これにより、注文の処理の際にどのお客さんの注文を扱っているかがわかります。
この例えでは、各お客さんの注文情報(PlayerUI
)を取得し、特別メニューの有無(MyUI
)をチェックし、現在のお客さん(Player
)を追跡して、注文に関する処理を行うというコードの関係性が表現されています。
ちなみに、MaybeMyUIPerPlayerは「プレイヤーごとのUI」と訳されます。

MaybeMyUIPerPlayerの詳細
クリックすると開きます。
「MaybeMyUIPerPlayer」は、各プレーヤーに対して特別なUIが存在するかどうかを示す変数やデータ構造を表しています。"Maybe"という単語が含まれているため、特別なUIが存在しないプレーヤーもある可能性があることを意味します。
具体的には、MaybeMyUIPerPlayer
は各プレーヤーをキーとして持ち、そのプレーヤーに特別なUIが存在する場合はそのUIを示す値を関連付けます。
ただし、特別なUIが存在しない場合、そのプレーヤーに対応する値は存在しない(またはnullなど)か、関連付けが行われない可能性があります。
コードでは、MaybeMyUIPerPlayer[Message.Player]
のようにして、特定のプレーヤーに関連する特別なUIを取得するために使用されています。
このコードでは、MaybeMyUIPerPlayer[Message.Player]
が存在しない場合、特別なUIはそのプレーヤーには関連付けられていないことを意味します。
特別なUIとは
クリックすると開きます。
「特別なUI」は、通常のUIとは異なる、特定の条件やコンテキスト下で表示されるUIを指す場合があります。
- アクセス権限や特別な条件を持つユーザー向けの特別な機能を提供するUI
- 例えば、管理者用の管理メニューや特権操作を行うためのUI。
- イベントやプロモーションなどの特別な場合に表示されるUI
- 期間限定の割引や特典を表示するバナーやポップアップなど。
- 個別のユーザーにカスタマイズされたUI
- ユーザーが選択したテーマや設定に基づいて表示が変化するUI。
- 特定のタスクやフローに関連する特別なUI
- 例えば、購入手続きが進行中の場合に表示される支払いフォームや確認画面など。
したがって、「特別なUI」は、一般的なUIとは異なる制約や条件を持ち、特定のユーザーや状況に適切な情報や機能を提供するために使用されるUIを指すことが多いです。

Player := Message.Playerの詳細
クリックすると開きます。
Player := Message.Player
は、Message.Player
の値を Player
という変数に代入しています。
変数はデータを一時的に保存するための箱のようなものであり、プログラムの途中で値を保持したり操作したりするために使用されます。ここでは、Message.Player
が現在のプレイヤーを表していると仮定します。
「Player := Message.Player」というコードは、イベントの発生元であるプレイヤーを取得しているわけですね。

:=
は、変数への値の代入を示す演算子です。右辺の値(Message.Player
)が左辺の変数(Player
)に代入されます。
この行の目的は、変数 Player
に現在のプレイヤーの値(Message.Player
)を格納することです。これにより、後続のコード内で Player
変数を使用して、現在のプレイヤーに関連する処理や操作を実行することができます。
なお、プログラミングでは、変数名は開発者によって自由に選ぶことができます。ここでは、Player
という変数名が使用されていますが、他の名前でも構いません。ただし、変数名は分かりやすく、意味を持つものにすることが推奨されます。
Player := Message.Player
の中の Message.Player
は、受け取った widget_message
からプレイヤーの情報を取得するためのものです。
Message.Player
は、widget_message
のプレイヤーを識別するための値(通常はプレイヤーの識別子や参照)を表しています。この値は、この関数が実行される際に渡された引数 Message
に含まれているものと仮定されます。
この行の目的は、受け取った Message
の中からプレイヤーの情報を取り出し、Player
という変数に代入することです。その後のコードでプレイヤーに関連する処理を行うために、この変数を使用します。
なぜ PlayerUI
や MyUI
を使用しなかったのかという点についてですが、コード全体を考慮すると、PlayerUI
と MyUI
は特定のプレイヤーのUI情報を表す変数です。
一方、Player := Message.Player
は単に現在のプレイヤーを取得するための一時的な変数です。
PlayerUI
や MyUI
は特定の目的や条件に応じて使用される変数であり、その意味や役割が異なります。
一方、Player := Message.Player
は単に処理のためにプレイヤーを取得するだけで、特定のUI情報に関連付ける必要がないため、別々の変数として定義されていると考えられます。
つまり、PlayerUI
や MyUI
のような特定のUI情報を表す変数が必要な場合には、それぞれの変数が利用されるでしょう。ただし、このコードではそれが必要ないため、別の変数 Player
が使用されたと推測できます。
上記の行で行われる処理の流れを順番に説明します。
PlayerUI
とMyUI
が存在するかどうかをチェックします。これは、GetPlayerUI
関数とMaybeMyUIPerPlayer
関数を使用して、Message.Player
に関連するUI情報を取得する処理です。
GetPlayerUI
関数は、特定のプレイヤー(Message.Player
)に関連するUI情報を返す関数です。MaybeMyUIPerPlayer
関数は、特定のプレイヤー(Message.Player
)に関連するもう1つのUI情報を返す関数です。
- もし
PlayerUI
とMyUI
の両方が存在する場合、以下の処理が実行されます。
Player
変数にMessage.Player
(特定のプレイヤー)が代入されます。- つまり、
Player
変数は特定のUI情報を持ったプレイヤーを指す変数となります。
- つまり、
これにより、特定のプレイヤーが特別なUIを持つ場合に、そのプレイヤーの情報を Player
変数に格納することができます。その後のコードでは、Player
変数を使用して特定のプレイヤーに関連する処理や操作を行うことができます。
このように、上記のコードは特定のUI情報を持つプレイヤーを指すための変数 Player
を設定する役割を果たしています。

ThisWidget := Message.Sourceの詳細
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
ThisWidget := Message.Source
は、与えられたウィジェットメッセージ(Message
)から、ウィジェットのソース(ボタン、テキストボックスなど)を取得して、ThisWidget
変数に代入する操作を行っています。
具体的には、Message
オブジェクトは、ウィジェットが発生したイベントに関する情報を含んでいます。その中のSource
プロパティには、そのイベントのソースとなったウィジェット(ボタンやキャンバスなど)が格納されています。
MessageオブジェクトのSourceプロパティは、イベントを発生させた要因であるウィジェットを取得するということですね。

ThisWidget := Message.Source
というコードは、Message
オブジェクトからソースウィジェットを取得し、それをThisWidget
変数に代入しています。これにより、処理の中でThisWidget
を使用して、特定のウィジェットに対する操作や情報の取得などを行うことができます。
例えば、StaleButtonUI := Player.FindButtonUI(ThisWidget)
という行で、FindButtonUI
関数がThisWidget
を引数として呼び出されています。この関数は、ThisWidget
(ボタン)に関連するボタンUIを検索して、その結果をStaleButtonUI
変数に代入します。
このように、ThisWidget := Message.Source
は、メッセージからソースウィジェットを取得して、そのウィジェットに関連する操作や情報の取得に使用される変数を初期化する役割を果たしています。
ThisWidget := Message.Source
Message.Source
の記述がない場合、次のような問題が発生する可能性があります。
ThisWidget
の値が未定義となる:ThisWidget
はMessage.Source
に割り当てられた値を参照しています。Message.Source
の記述がない場合、ThisWidget
は未定義(または無効な値)となります。- 未定義の値でボタンUIを検索しようとすると、エラーが発生する可能性があります。
- ボタンUIの検索が正しく機能しない:
StaleButtonUI := Player.FindButtonUI(ThisWidget)
の行では、ThisWidget
に基づいてボタンUIを検索しています。ThisWidget
が未定義の場合、ボタンUIを正しく検索できず、意図した処理が行われない可能性があります。
- エラーメッセージの表示が不適切:
else
のブロックに記述されたエラーメッセージPrint("~ERROR: No buttonui found!")
は、ボタンUIが存在しない場合に表示される予定です。- しかし、
ThisWidget
が未定義であるため、エラーメッセージは正確な状況を伝えず、適切なデバッグやトラブルシューティングが困難になる可能性があります。
この問題を回避するには、ThisWidget
の値の正当性を確認し、未定義の場合に適切なエラーハンドリングを行うことが重要です。
例えば、未定義の場合にはエラーメッセージを表示したり、ボタンUIの検索をスキップして処理を続行したりすることが考えられます。また、デバッグ用の情報を出力することで、問題の特定や修正を容易にすることができます。
widget_message構造体の詳細
クリックすると開きます。
widget_message
は、Unreal Engineと呼ばれるゲーム開発エンジンで使用されるデータ構造の一つです。
このデータ構造は、ウィジェット(ボタン、テキストボックスなどのインタラクティブな要素)に関連するイベントが発生したときに、そのイベントに関する情報を格納するために使用されます。
例えば、ユーザーがボタンをクリックしたり、テキストボックスに入力したりすると、それぞれのイベントが発生します。
このようなイベントには、どのボタンが押されたかや、どのテキストが入力されたかといった情報が必要です。
widget_message
は、それらの情報を保持するための入れ物の役割を果たします。
具体的には、widget_message
は次の情報を格納します:
Player
(プレイヤー):- イベントをトリガーしたプレイヤー(ユーザー)に関する情報です。
- たとえば、ユーザーがボタンをクリックした場合、どのプレイヤー(ユーザー)がクリックしたのかを判断するために使います。
Source
(ソース):- イベントをトリガーした具体的なウィジェット(ボタンやテキストボックス)に関する情報です。
- たとえば、ユーザーがボタンをクリックした場合、どのボタンがクリックされたのかを判断するために使います。
widget_message
は、イベントが発生した瞬間に生成され、関連するデータを保持します。これにより、プログラムはどのユーザーがどのウィジェットの操作を行ったのかを知ることができます。
簡単に言えば、widget_message
は、ユーザーがウィジェットを操作したときにその情報をキャプチャし、処理や反応に利用するための特別なデータ構造です。この構造体は、Unreal Engine内でイベントベースのプログラミングを行う際に重要な役割を果たします。
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):の必要性
クリックすると開きます。
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
の記述は、以下のような目的を持っています。
- プレイヤー固有のユーザーインターフェース(UI)を取得する:
GetPlayerUI
関数を使用して、Message.Player
(メッセージの送信元プレイヤー)に関連するプレイヤーUIを取得し、PlayerUI
として定義します。- このプレイヤーUIは特定のプレイヤーに対して表示される固有のUI要素のセットです。
- 同様に、
MaybeMyUIPerPlayer
リストから、Message.Player
に関連するMyUI
を取得します。
- 条件分岐のためのブロックを作成する:
if (condition):
の形式で条件分岐を開始します。- この場合、
PlayerUI
とMyUI
の両方が存在するか確認します。 - この条件式が真である場合、つまり
PlayerUI
とMyUI
の両方が存在する場合に、そのブロック内の処理が実行されます。
- プレイヤー情報とウィジェットメッセージの取得:
- 条件式が真の場合に実行されるコードブロックでは、
Player
にMessage.Player
の値が割り当てられます。 - これにより、そのブロック内で
Message.Player
の値を簡単に参照できるようになります。 - また、
ThisWidget
にMessage.Source
の値が割り当てられます。 - これにより、ウィジェットメッセージに関連する現在のウィジェットを識別できます。
- 条件式が真の場合に実行されるコードブロックでは、
- ボタンUIの検索と操作の実行:
- ブロック内のコードでは、プレイヤーインターフェースの
Player
オブジェクトに含まれるFindButtonUI
関数を使用して、ThisWidget
に対応するボタンUIを検索します。 - ボタンUIが存在する場合は、それを
ThisButtonUI
として参照します。 - そして、ボタンUIが削除可能な場合は
DeleteUI
関数を呼び出し、ボタンのトリガーをアクティブにするためにThisButtonUI.ActivateTrigger(Player)
を実行します。
- ブロック内のコードでは、プレイヤーインターフェースの
- ボタンUIが存在しない場合のエラーハンドリング:
- ボタンUIが存在しない場合は、エラーメッセージ
"~ERROR: No buttonui found!"
を出力します。 - これは、ボタンUIの特定やデバッグ時に役立ちます。
- ボタンUIが存在しない場合は、エラーメッセージ
このようなコードブロックを使用することで、プレイヤーUIとボタンUIに関連する操作を適切に処理するための制御フローを作成できます。
if (PlayerUI := Get~が無い場合に想定される問題点if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
の記述がない場合、以下のような問題が起こる可能性があります。
- プレイヤーUIとMyUIの取得が保証されない:
GetPlayerUI[Message.Player]
によってプレイヤーUIを取得し、MaybeMyUIPerPlayer[Message.Player]
によってMyUIを取得しています。- これらの取得が保証されない場合、後続のコードでこれらのオブジェクトを使用しようとするとエラーが発生します。
- 処理の条件分岐が不正確になる:
if
文のブロック内の処理は、PlayerUI
とMyUI
の両方が存在する場合にのみ実行されます。- これにより、後続の処理がプレイヤーUIとボタンUIに対して適切な操作を行うことが保証されます。
- 条件分岐がないと、存在しないUIオブジェクトに対して処理を試みる可能性があり、エラーの原因となるでしょう。
- ボタンUIの検索や操作を行えない:
FindButtonUI
やDeleteUI
、ThisButtonUI.ActivateTrigger(Player)
のようなボタンUIに関連する操作は、条件分岐の中でのみ実行されるため、条件式がないとこれらの処理も実行されません。- その結果、プレイヤーUI上のボタンの動作が正しく制御されなくなります。
したがって、if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
の記述が欠落すると、プレイヤーUIとボタンUIに関連する操作が意図したように機能しなくなる可能性があります。
また、存在しないオブジェクトにアクセスしようとするエラーや予期しない振る舞いが生じる可能性もあります。


今回のコードの最大の目的は、特定のプレイヤーが特定のボタンを選択した場合に関連する操作や処理を実行することだと思うんですけど、先ほどの条件式が無いと「特定のプレイヤーが特定のボタンを選択したのかわからない」ですよね?
その通りです。条件式 if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?): の目的は、特定のプレイヤーが特定のボタンを選択したかどうかを確認することです。
条件式がない場合、特定のプレイヤーが特定のボタンを選択したのかどうかを判断する手段がなくなります。条件式を使用することで、プレイヤーUIとユーザーが選択したボタンUIを正確に特定し、それに関連する操作や処理を実行できます。

このデータ構造は、ウィジェットに関連するイベントが発生したときに、そのイベントに関する情報を格納するために使用されます。について
クリックすると開きます。
このデータ構造は、ウェブページ上のボタンやテキストボックスなどのインタラクティブな要素に関連するイベントについての情報を格納するのに似ています。
想像してください、あるウェブページには複数のボタンがあります。それぞれのボタンは特定の機能やアクションを実行するために存在しています。
例えば、「送信」というボタンをクリックするとメッセージが送信されるとした場合、そのボタンに関連するイベントが発生します。
このデータ構造は、そのようなイベントに関する情報を格納するのに役立ちます。
具体的には、どのボタンが押されたかや、どのユーザーがアクションを実行したのかといった情報を保持します。
例えば、特定のユーザー(プレイヤー)がゲーム内の特定のボタンを押した場合、そのユーザーの情報や押されたボタンに関する詳細情報をこのデータ構造に格納することができます。
これにより、適切なアクションや処理を実行するための基盤が整います。
要するに、ウェブページ上のボタンイベント情報を表すデータ構造と同様に、このデータ構造はインタラクティブな要素に関連するイベント情報を処理・管理するのに役立ちます。
StaleButtonUI := Player.FindButtonUI(ThisWidget)の詳細:途中FindButtonUI関数に進む
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
このコードでは、StaleButtonUIという変数に対して、Playerオブジェクトによって提供されるFindButtonUI関数を使用して、特定のウィジェット(ThisWidget)に関連付けられたボタンUIを検索しています。以下に徹底解説を行います。
- StaleButtonUI := Player.FindButtonUI(ThisWidget)
- FindButtonUI関数は、Playerオブジェクトに定義された関数であり、プレイヤーに関連付けられたボタンUIを検索します。
- ThisWidgetは、引数として渡されたウィジェットメッセージ(Message.Source)を指します。
- このコードは、現在のプレイヤー(Player)の中から、ThisWidgetに関連するボタンUIを検索し、StaleButtonUIに代入します。
- "Stale"という単語は、意味的には「古い」や「使用されなくなった」という意味ですが、具体的にはこのコードではボタンUIの検索結果を指すための一時的な変数名として使用されています。
以下はコードの他の部分との関連性を説明します:
- もし StaleButtonUI が存在する場合 (if (ThisButtonUI := StaleButtonUI?):)
- ボタンUIが見つかった場合の条件分岐です。
- もしボタンUIがボタンがクリックされたときに削除される設定になっている場合 (if ThisButtonUI.RemovesUIOnClick?):
- DeleteUI(Message): UIを削除する操作を実行します。
- ThisButtonUI.ActivateTrigger(Player): ボタンUIのトリガーをアクティベートします。
- もし StaleButtonUI が存在しない場合 (else: ボタンUIが存在しない場合)
- Print("~ERROR: No buttonui found!"): エラーメッセージを表示します。
以上が、StaleButtonUI := Player.FindButtonUI(ThisWidget)のコードの解説です。これは特定のプレイヤーに関連するボタンUIを検索するための一連の手順を表しています。
深掘りまず、Player.FindButtonUI(ThisWidget)
とは、指定された ThisWidget
を持つ ButtonUI
をプレイヤーに関連付けられたものの中から検索するための関数です。
プログラムの中で、Player
はプレイヤーを表すオブジェクト、ThisWidget
はウィジェット(ボタン)を表すオブジェクトです。
Player.FindButtonUI(ThisWidget)
の処理の流れを簡単に説明します。
ButtonUI
のリスト(ButtonUI
を要素とするリスト)をイテレート(順番に処理)します。- 現在の
ButtonUI
をThisButtonUI
として取得します。 ThisButtonUI
のButtonWidgetPerPlayer
から、Agent
(エージェント)に関連付けられたウィジェット(ボタン)を取得します。これをStaleWidget
として取得します。ThisWidget
とStaleWidget
を比較して、一致するかどうかを確認します。- 一致する場合は、
ThisButtonUI
をオプション型{}
でラップして返します。一致しない場合は、次のButtonUI
を検索します。 - ループが終了した場合、
false
を返します。つまり、一致するButtonUI
を見つけられなかったことを示します。
この関数の目的は、特定のウィジェット(ボタン)に関連付けられた ButtonUI
を検索し、その結果を返すことです。また、一致する ButtonUI
が見つからなかった場合は、エラーメッセージを表示します。
なお、オプション型 {}
は、値が存在する場合にはその値を保持し、値が存在しない場合には false
を持つデータ型です。
つまり、定されたウィジェット(ThisWidget
)がプレイヤー(Player
)に関連付けられた ButtonUI
の中に存在するかどうかを確認しています。

Player
は、プレイヤーを表すオブジェクトです。ButtonUI
は、ボタンに関する情報を持つオブジェクトです。
Player.FindButtonUI(ThisWidget)
の目的は、指定されたウィジェットがプレイヤーに関連付けられたどのボタン(ButtonUI
)に属しているかを検索することです。存在する場合は、そのボタン(ButtonUI
)を返します。存在しない場合は、false
を返します。
このようにして、特定のウィジェットがどのボタンに属しているのかを確認することができます。
ThisWidget := Message.SourceとStaleButtonUI := Player.FindButtonUI(ThisWidget)の関係性
クリックすると開きます。
「ThisWidget := Message.Source」は、イベントを発生させた要因であるウィジェット(ボタン)を取得するためのコードです。
一方、「StaleButtonUI := Player.FindButtonUI(ThisWidget)」は、PlayerオブジェクトのFindButtonUI関数を使用して、特定のウィジェットに関連付けられたボタンUIを検索するためのコードです。
具体的な関係と違いを説明します:
ThisWidget := Message.Source:
- ThisWidgetは、イベントを発生させた要因であるウィジェット(ボタン)を取得するための変数です。
- Messageは、イベントに関連する情報を含むオブジェクトです。
- Sourceは、イベントの発生元であるウィジェットを指します。
- このコードは、イベントメッセージのSourceプロパティからウィジェットを取得し、ThisWidget変数に代入します。
- つまり、このコードは、イベントの発生元であるウィジェット(ボタン)をThisWidget変数として保持するためのものです。
StaleButtonUI := Player.FindButtonUI(ThisWidget):
- FindButtonUI関数は、Playerオブジェクトに定義された関数であり、プレイヤーに関連付けられたボタンUIを検索します。
- Playerは、イベントを発生させたプレイヤーを指します。
- ThisWidgetは、前述の手順で取得したイベントの発生元であるウィジェット(ボタン)を指します。
- このコードは、Playerオブジェクトの中から、ThisWidgetに関連するボタンUIを検索し、StaleButtonUI変数に代入します。
- つまり、このコードは、特定のプレイヤーに関連するボタンUIを検索して、StaleButtonUI変数として保持するためのものです。
要するに、"ThisWidget := Message.Source"はイベントを発生させた要因であるウィジェット(ボタン)を取得し、"StaleButtonUI := Player.FindButtonUI(ThisWidget)"はそのウィジェットに関連付けられたボタンUIを検索します。
これらの手順を組み合わせることで、特定のプレイヤーに関連する特定のボタンUIを見つけることができます。
【例】
あなたが店員さん(Player)であり、それぞれのテーブルにボタンがあるカフェにいると想像してください(ButtonUI)。お客さんの中に手を挙げて注文をしたい人がいた場合(Event)、どのお客さん(ThisWidget)が手を挙げたかを特定し、そのお客さんのテーブルのボタンを見つけ出したいと思います(StaleButtonUI)。
このシナリオでは次のような関係性があります:
- ThisWidget := Message.Sourceは、手を挙げたお客さんを特定することに似ています。
- StaleButtonUI := Player.FindButtonUI(ThisWidget)は、そのお客さんのテーブルのボタンを見つけることに似ています。
つまり、「ThisWidget := Message.Source」を使用することで、イベント(手を挙げること)を起こした特定のお客さん(ThisWidget)を特定し、「StaleButtonUI := Player.FindButtonUI(ThisWidget)」を使用することで、そのお客さんに関連するテーブルのボタン(ButtonUI)を特定します。
PlayerとAgentの使い分けについて
クリックすると開きます。
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
Player.FindButtonUI(ThisWidget)
のコードは、Player
という変数がMessage.Player
を指しているものと想定されています。
Player
はMessage.Player
を参照しており、そのプレイヤーに関連するButtonUI
を取得するために使用されています。
一方、(Agent : agent).FindButtonUI(ThisWidget : widget):?buttonui
の定義では、Player
ではなく代わりにAgent
という広い意味での変数名が使用されています。
これは、すべてのプレイヤーに関連するButtonUI
が存在する可能性があるためです。
Player
型はagent
型の一部であり、agent
型はPlayer
型を含むより一般的な型として機能します。
if (ThisButtonUI := StaleButtonUI?):の詳細
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if ThisButtonUI.RemovesUIOnClick?:
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
if (ThisButtonUI := StaleButtonUI?):
の部分は以下の役割を果たします。
StaleButtonUI
を評価して、その結果をThisButtonUI
に代入します。ThisButtonUI
が存在する(true
またはtruthy
)場合は、条件式が真となり、条件式のブロックが実行されます。ThisButtonUI
が存在しない(false
またはfalsy
)場合は、条件式が偽となり、条件式のブロックはスキップされます。
StaleButtonUI
を明示的に評価し、その結果を変数に格納しつつ、ThisButtonUI
が存在するかどうかを同時にチェックしています。
具体的な動作を以下に示します。これをステップバイステップで見ていきましょう。
StaleButtonUI
を評価します。- もし
StaleButtonUI
が存在し、truthy
である場合、ThisButtonUI
にその値を代入します。 ThisButtonUI
が存在する(true
またはtruthy
)場合、条件式のブロックが実行されます。ThisButtonUI
が存在しない(false
またはfalsy
)場合、条件式のブロックはスキップされ、else
節内のコードが実行されます。
if ThisButtonUI.RemovesUIOnClick?~の詳細│DeleteUIの定義(含)
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if(ThisButtonUI.RemovesUIOnClick?):
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
これはボタンがクリックされた場合にUIを削除する処理です。
if (ThisButtonUI.RemovesUIOnClick?):
の行では、ボタンがクリックされた際にUIを削除するかどうかをチェックしています。- つまり、
ThisButtonUI
というオブジェクト内のRemovesUIOnClick
というプロパティがtrue
かどうかを確認しています。
- つまり、
- もしボタンがクリックされたときにUIを削除するように設定されている場合(
RemovesUIOnClick
がtrue
の場合)、次の行のDeleteUI(Message)
が実行されます。- これにより、
Message
に関連するUIが削除されます。
- これにより、
要するに、この処理はボタンがクリックされたときにUIを削除するかどうかを判断し、削除の設定があれば対応するUIを削除します。

DeleteUI(Message)の詳細
クリックすると開きます。
DeleteUI(Message)
は、指定されたMessage
に応じてUIを削除する関数です。
この関数は、以下の手順で実行されます:
Message
には、プレイヤーと関連する情報が含まれています。- たとえば、
Message
が「プレイヤーAのUIを削除してください」という要求だった場合、Message
には「プレイヤーA」に関する情報が含まれています。
- たとえば、
MaybeMyUIPerPlayer
という辞書から、Message
に指定されたプレイヤーに関連する値を取得します。- この値は、そのプレイヤーにUIが作成されたかどうかを示します。
- 取得した値が
false
(UIが削除されている)であれば、何も行いません。- UIが存在しないため、削除する必要がありません。
- 取得した値が
true
(UIが作成されている)であれば、UIを削除します。
この関数は、指定されたプレイヤーのUIが存在する場合にのみ、UIの削除を試みるという動作を実現します。これにより、不要なUIのリソース消費を避けることができます。
ThisButtonUI.ActivateTrigger(Player)~の詳細│ActivateTriggerの定義(含)
クリックすると開きます。
HandleSelectedUIButton(Message: widget_message): void =
# プレイヤーUIとボタンUIに関連する操作を処理します
if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):
Player := Message.Player
# プレイヤー情報を取得します
ThisWidget := Message.Source
# ウィジェットメッセージを取得します
StaleButtonUI := Player.FindButtonUI(ThisWidget)
# ボタンUIを検索します
if (ThisButtonUI := StaleButtonUI?):
# ボタンUIが存在する場合
if(ThisButtonUI.RemovesUIOnClick?):
# ボタンがクリックされた際にUIを削除する場合
DeleteUI(Message)
# UIを削除します
ThisButtonUI.ActivateTrigger(Player)
# ボタンのトリガーをアクティベートします
else: # ボタンUIが存在しない場合
Print("~ERROR: No buttonui found!")
# エラーメッセージを出力します
このコードは、もしStaleButtonUI
が存在する場合は、ThisButtonUI
にその値を代入し、ThisButtonUI.ActivateTrigger(Player)
を実行します。そうでない場合は、Print("~ERROR: No buttonui found!")
を実行してエラーメッセージを出力します。
具体的に各行を見てみましょう。
if (ThisButtonUI := StaleButtonUI?):
:=
は、Pythonの代入と同時に条件をチェックする演算子です。
StaleButtonUI
が存在する場合、その値がThisButtonUI
に代入されます。
ThisButtonUI.ActivateTrigger(Player)
ThisButtonUI
はボタンUIを指し、.ActivateTrigger(Player)
はボタンのトリガーをアクティベートするメソッドを呼び出します。
- 具体的なアクティベーションの内容はビジネスロジックに依存します。
else:
if
文の条件式が成立しない場合、つまりStaleButtonUI
が存在しない場合に実行される部分です。
Print("~ERROR: No buttonui found!")
- エラーメッセージ
~ERROR: No buttonui found!
を表示するためのPrint
文です。
- エラーメッセージ
つまり、このコードは、選択されたボタンのUIが存在する場合はそのトリガーをアクティベートし、存在しない場合はエラーメッセージを表示します。
ボタンのトリガーをアクティベートする理由
クリックすると開きます。
ボタンのトリガーをアクティベートする理由は、プレイヤーがボタンをクリックしたときに、そのボタンが関連付けられているアクションや機能を実行するためです。
通常、ボタンをクリックすると、特定の操作や処理をトリガーするためのコードが実行されます。
UIの削除後にボタンのトリガーをアクティベートする理由は、以下のようなシナリオを想定しています:
- プレイヤーがボタンをクリックすると、対応するUIが表示される。
- ボタンのクリックを処理した後、そのUIを不要になったため削除する。
- UIを削除した後も、ボタンのトリガーをアクティベートすることで、プレイヤーのアクションを引き続き処理できる。
UIを削除してもボタンのトリガーをアクティベートする理由は、UIとボタンの関連性が分離されているためです。削除されたUIはプレイヤーには表示されなくなりますが、ボタン自体はまだ存在し、ボタンをクリックしてアクティベートすることで、関連するアクションや機能を実行することができます。
UIの削除後にボタンのトリガーをアクティベートすることで、プレイヤーがボタンをクリックしたときに適切な処理が行われるようになります。
DeleteUI(Message : widget_message) : void=の詳細
DeleteUI(Message : widget_message) : void=
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
PlayerUI.RemoveWidget(MyUI)
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
このコードは、DeleteUI
という関数の定義です。
以下に行ごとに解説します:
- 関数の宣言
DeleteUI(Message: widget_message): void
は、DeleteUI
という関数を宣言しています。- この関数は、
Message
という名前のwidget_message
型の引数を受け取り、戻り値はvoid
(何も返さないこと)です。
- この関数は、
- もし(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?) ならば:
- この行は
if
文の条件式の始まりです。 PlayerUI := GetPlayerUI[Message.Player]
は、GetPlayerUI
関数を使ってMessage.Player
に関連付けられた UI を取得し、PlayerUI
という変数に代入しています。MyUI := MaybeMyUIPerPlayer[Message.Player]?
は、MaybeMyUIPerPlayer
関数を使ってMessage.Player
に関連付けられた個別の UI(MyUI)を取得し、MyUI
という変数に代入しています。?
が付いているので、MaybeMyUIPerPlayer[Message.Player]
の戻り値が存在しない場合、変数MyUI
はnull
や未定義の値になる可能性があります。
- PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
は、変数PlayerUI
が持つオブジェクトのRemoveWidget
メソッドを呼び出し、引数にMyUI
を渡しています。- これにより、
PlayerUI
からMyUI
というウィジェットが削除されます。
- MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
は、MaybeMyUIPerPlayer[Message.Player]
をfalse
に設定します。- これにより、
Message.Player
に関連付けられた個別の UI がもはや存在しないことを示します。
- これにより、
if
文のブロックは空であり、何も追加の処理は行われません。変数の割当だけが行われます。
上記のコードの最大の目的は、特定のプレイヤーのインターフェース(UI)から個別のUIを削除し、関連する状態を更新することです。
以下に、コードの目的をプログラミング初心者向けに解説します:
- プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
GetPlayerUI
関数を使用して、Message.Player
に関連付けられたUIを取得します。- それを
PlayerUI
という変数に代入します。
- それを
MaybeMyUIPerPlayer
関数を使用して、Message.Player
に関連付けられた個別のUI(MyUI)を取得します。- それを
MyUI
という変数に代入します。
- それを
- PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
を呼び出すことで、PlayerUI
からMyUI
という特定のウィジェットを削除します。- つまり、プレイヤーのUIから個別のUIを削除することが目的です。
- MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
MaybeMyUIPerPlayer[Message.Player]
をfalse
に設定します。- これにより、
Message.Player
に関連付けられた個別のUIがもはや存在しないことを表します。
- これにより、
まとめると、特定のプレイヤーのUIを削除し、関連する状態を更新するために使用されます。

widget_message構造体の詳細
クリックすると開きます。
widget_message
は、イベントがウィジェットによってシグナルされたときに使用されるパラメータの構造体(struct)です。
詳細は以下のとおり。
構造体とは、複数の関連するデータをまとめて管理するためのデータ型です。
widget_message
構造体には、以下のデータメンバ(データの要素)が含まれています:
Player
:- このメンバは
player
という型で、イベントをトリガーしたプレイヤーを表します。 - つまり、イベントがどのプレイヤーによって発生したのかを特定するための情報です。
- このメンバは
Source
:- このメンバは
widget
という型で、イベントをトリガーしたウィジェット自体を表します。 - ウィジェットは、画面上に表示されるユーザーインターフェースの要素(ボタン、テキストボックスなど)を指します。
- このメンバは、どのウィジェットがイベントを発生させたのかを示すために使用されます。
- このメンバは
widget_message
構造体は、特定のイベントが発生した際に、プレイヤーやウィジェットなどの情報を格納するために利用されます。
これにより、イベントがどのコンテキストで発生したかを特定し、必要な処理を行うことができます。

if (PlayerUI := GetPlayerUI[Message.Player]), (MyUI := MaybeMyUIPerPlayer[Message.Player]?):の詳細
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
まず、if
は条件文を表すキーワードで、その後の括弧内の条件が真(true)であれば、そのブロック内のコードが実行されます。括弧内の条件には2つの処理が含まれています。
PlayerUI := GetPlayerUI[Message.Player]
:- この行では、
GetPlayerUI[Message.Player]
という関数を呼び出して、プレイヤーに関連付けられたUI(ユーザーインターフェース)を取得しています。 :=
は、代入(変数に値を割り当てる)と同時に条件を評価する演算子です。- つまり、この行で
PlayerUI
という変数にGetPlayerUI[Message.Player]
の戻り値(プレイヤーUI)が代入されます。
- この行では、
(MyUI := MaybeMyUIPerPlayer[Message.Player]?)
:- この行では、
MaybeMyUIPerPlayer[Message.Player]
というフラグを取得しています。 ?
はオプションチェーン演算子と呼ばれ、MaybeMyUIPerPlayer[Message.Player]
が存在する場合にだけ、その値を取得することを示します。- この行の
MyUI
という変数にフラグの値が代入されます。
- この行では、
この条件文は、プレイヤーUIと関連付けられたUIの有無をチェックしています。GetPlayerUI[Message.Player]
はプレイヤーに関連付けられたUIを取得し、MaybeMyUIPerPlayer[Message.Player]
はUIの有無を示すフラグです。
もしUIが存在する場合、この条件は真となり、それに続くブロック内のコードが実行されます。
プログラムの流れとしては、この条件文でUIの有無を確認し、UIが存在する場合にさまざまな処理を行うという制御フローを表しています。
GetPlayerUI関数の詳細
クリックすると開きます。
GetPlayerUI
関数は、与えられたPlayer
に関連付けられたplayer_ui
コンポーネントを返す関数です。Player
に関連付けられたplayer_ui
が存在しない場合は失敗します。
この関数は、ゲーム開発などのコンテキストで使用されるもので、特定のプレイヤーに関連付けられたユーザーインターフェース(UI)コンポーネントを取得するために使われます。
以下は関数のシグネチャの解説です:
構文: GetPlayerUI(Player: player) -> player_ui
引数:
Player
: プレイヤーを表す情報です。
戻り値:
player_ui
:Player
に関連付けられたUIのコンポーネントです。
この関数を呼び出すことで、指定したプレイヤーに関連付けられたUIを取得することができます。
UIが存在しない場合は、失敗となります。
player_uiクラスの詳細
クリックすると開きます。
player_ui
クラスは、プレイヤーのUIにウィジェットを追加したり削除したりするためのメインのインタフェースです。
このクラスは、ゲーム開発などのコンテキストで使用されます。プレイヤーのUIにウィジェット(グラフィカルな要素やコントロール)を追加したり、削除したりするための機能を提供します。
以下にplayer_ui
クラスの詳細を説明します:
メンバー:
- このクラスには関数がありますが、データメンバーはありません。
関数:
AddWidget
:- デフォルトの
player_ui_slot
の設定オプションを使用して、ウィジェットをplayer_ui
に追加します。
- デフォルトの
AddWidget
:- オプションの
Slot
を使用して、ウィジェットをplayer_ui
に追加します。 - 追加するウィジェットの構成オプションを指定するために
Slot
を使用します。
- オプションの
RemoveWidget
:player_ui
から指定したウィジェットを削除します。
player_ui
クラスは、プレイヤーのUIに対してウィジェットを追加したり削除したりするための便利な機能を提供します。

(MyUI := MaybeMyUIPerPlayer[Message.Player]?):の詳細
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
(MyUI := MaybeMyUIPerPlayer[Message.Player]?)
は、変数MyUI
を宣言し、MaybeMyUIPerPlayer[Message.Player]
から取得した値を代入します。
ただし、MaybeMyUIPerPlayer[Message.Player]
が存在しない場合、変数MyUI
はnull
(またはNone
)となります。
以下に詳細を説明します:
MaybeMyUIPerPlayer
は、Message.Player
に関連付けられたUIのリストや辞書などを表す変数またはデータ構造です。[Message.Player]
は、Message.Player
をキーとして、MaybeMyUIPerPlayer
からUIを取得する操作を行います。?
は、Option型やNullable型と呼ばれる機能です。- もし取得したUIが存在しない場合、
MyUI
にはnull
(またはNone
)が代入されます。
- もし取得したUIが存在しない場合、
つまり、(MyUI := MaybeMyUIPerPlayer[Message.Player]?)
の行では、プレイヤーに関連付けられたUIを取得し、もし存在すればMyUI
に代入し、存在しなければMyUI
をnull
(またはNone
)として初期化します。

その後のコードでは、MyUI
がnull
(またはNone
)でない場合に、適切な処理を行っているように見受けられます。
PlayerUIとMyUIの違い
クリックすると開きます。
PlayerUI
とMyUI
は、それぞれ異なる変数であり、以下にその違いを説明します。
PlayerUI
:PlayerUI
は、GetPlayerUI[Message.Player]
から取得される特定のプレイヤーに関連付けられたUI(ユーザーインターフェース)を表します。GetPlayerUI
関数は、与えられたプレイヤーに関連付けられたUIのコンポーネントを返すものです。- この変数には、
Message.Player
に対応するプレイヤーのUIが代入されます。
MyUI
:MyUI
は、MaybeMyUIPerPlayer[Message.Player]
から取得されるUIを表します。MaybeMyUIPerPlayer
は、プレイヤーごとに関連付けられたUIのリストや辞書などのデータ構造を指します。- この変数には、
Message.Player
に対応するプレイヤーのUIが存在する場合はその値が代入され、存在しない場合はnull
(またはNone
)が代入されます。
要点まとめ:
PlayerUI
は、特定のプレイヤーに関連付けられたUIを表します。MyUI
は、プレイヤーごとに関連付けられたUIの存在を検証するための変数であり、存在する場合はその値を保持します。
【イメージ】
プレイヤーに関連付けられたUI(User Interface)を身近なものに例えると、以下のように説明できます:
PlayerUI
(プレイヤーのUI):- 考えてみてください、あなたが自分のスマートフォンを持っている場合、それはあなた専用のUIです。
- スマートフォンはあなたが使うためにデザインされ、アプリや設定などを操作するための機能を提供します。
- この場合、あなた自身がプレイヤーであり、スマートフォンがプレイヤーに関連付けられたUI(PlayerUI)です。
MyUI
(自分のUI):- これを説明するためには、ショッピングモールのロッカールームが良い例です。
- あなたはショッピングモールに行き、アイテムを購入するために指定されたロッカールームを利用します。
- ロッカールームはプレイヤー(つまり、あなた)に関連付けられたUIと考えることができます。
- そして、ロッカールームが他の人に秘密として提供されないようにするために、ロッカーの中にはあなたのアイテムを保管するためのプライベートなスペースがあります。
- これをあなたの個別のUI(MyUI)と見なすことができます。
- つまり、ロッカールーム全体がPlayerUIであり、ロッカーはMyUIに相当します。
要するに、PlayerUIはあなたに関連付けられた全体的なUIであり、MyUIはプレイヤーごとに特定のエレメントまたは領域に関連付けられた個別のUI要素です。


PlayerUIは全体の機能を提供し、MyUIは個人の特定の要素やリソースを提供するということですね!
与えられたコードの文脈に基づいて解釈すると、PlayerUI
とMyUI
は共にプレイヤーに関連付けられたUIを取得する部分ですが、それぞれ異なる役割を果たしています。
PlayerUI := GetPlayerUI[Message.Player]
の部分は、Message.Player
に関連付けられたプレイヤー全体のUIを取得しています。
これは全てのプレイヤーに共通のUIであり、プレイヤーが共通の操作や情報にアクセスするために使用されます。
一方で、(MyUI := MaybeMyUIPerPlayer[Message.Player]?)
は、Message.Player
に関連付けられた個別のUI(MyUI)を取得しています。
この行のコードはMaybeMyUIPerPlayer[Message.Player]
メソッド(あるいは関数)を呼び出していますが、疑問符(?)が付いていることから、個別のUIが存在しない場合にはnull
やデフォルトの値が返される可能性があることを示しています。
この個別のUIは、プレイヤーごとに異なる設定やプレイヤー固有の情報にアクセスするために使用されるものです。
要するに、PlayerUI
はプレイヤー全体のUIを取得するための変数であり、MyUI
は個別のプレイヤーが利用するためのUIを取得するための変数として利用されています。

if(PlayerUI := ~r[Message.Player]?):の記述理由
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
「if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):」という部分は、以下の目的を持っています。
- プレイヤーのUIと個別のUIを取得し、それぞれを
PlayerUI
とMyUI
に代入する。
GetPlayerUI[Message.Player]
という関数を使用して、Message.Player
に関連付けられたプレイヤーのUIを取得します。MaybeMyUIPerPlayer[Message.Player]
という関数を使用して、Message.Player
に関連付けられた個別のUI(MyUI)を取得します。
- 取得したUIが存在するかどうかをチェックする。
if
文を使用して、PlayerUI
とMyUI
の取得が成功したかどうかをチェックします。PlayerUI := GetPlayerUI[Message.Player]
の部分で、PlayerUI
にGetPlayerUI[Message.Player]
の結果を代入します。MyUI := MaybeMyUIPerPlayer[Message.Player]
の部分で、MyUI
にMaybeMyUIPerPlayer[Message.Player]
の結果を代入します。MaybeMyUIPerPlayer[Message.Player]?
の部分で、MaybeMyUIPerPlayer[Message.Player]
が存在する場合は、その結果を返します。
- 条件が真の場合、UIの削除と状態の更新を行います。
PlayerUI.RemoveWidget(MyUI)
を呼び出して、PlayerUI
からMyUI
を削除します。MaybeMyUIPerPlayer[Message.Player]
をfalse
に設定して、関連する状態を更新します。
この部分の目的は、特定のプレイヤーのUIと個別のUIを取得し、それらが存在する場合には削除と状態の更新を行うことです。
これにより、プレイヤーのUIの操作や状態の管理を行う際に便利です。
:=
は、一部のプログラミング言語(例: PythonのWalrus operator)で導入されている代入と比較を同時に行う構文です。
ここでは PlayerUI := GetPlayerUI[Message.Player]
で GetPlayerUI[Message.Player]
を PlayerUI
に代入し、同様に MyUI := MaybeMyUIPerPlayer[Message.Player]
で MaybeMyUIPerPlayer[Message.Player]
を MyUI
に代入しています。
このコードを使うことで、取得したUIを安全に操作し、関連する状態を適切に更新することができます。
削除するUIの存在の確認ってことですね。

PlayerUI.RemoveWidget(MyUI)の詳細
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
「PlayerUI.RemoveWidget(MyUI)」は、プレイヤーのユーザーインターフェース(UI)から特定のUI要素(MyUI)を実際に削除するためのコードです。
詳細は以下のとおり。
プレイヤーのUIを管理するPlayerUIオブジェクトがあり、その中から特定のUI要素(MyUI)を削除したい場合、PlayerUIオブジェクトの「RemoveWidget」メソッドを使用します。このメソッドは、指定したUI要素を取り除くために使用されます。
具体的なコードの動作は、以下の通りです。
- PlayerUIオブジェクトの「RemoveWidget」メソッドを呼び出します。
- 「PlayerUI.RemoveWidget(MyUI)」の部分が呼び出しの記述です。
- PlayerUIオブジェクトは、プレイヤーに関連したUIを管理しているオブジェクトです。
- 「MyUI」は、削除したいUI要素を示す変数名です。
- PlayerUIからMyUIが削除されます。
- 呼び出された「RemoveWidget」メソッドによって、PlayerUIからMyUIが取り除かれます。
このコードは、特定のプレイヤーのUIから特定のUI要素を削除するために使われます。
例えば、プレイヤーが表示しているメニューやボタンなどを変更する場合に使用されますね。
削除する前にUI要素の存在を確認するために、前述した条件文を使用しています。

RemoveWidget関数の詳細
クリックすると開きます。
RemoveWidget関数は、プレイヤーのUI(User Interface)を管理するオブジェクトであるPlayerUIから、指定したウィジェットを取り除くために使用されます。
ウィジェットは、ユーザーインターフェースの一部としてボタン、テキストボックス、イメージなどの要素を指します。
詳細は以下のとおり。
- RemoveWidget関数は、PlayerUIオブジェクト自体が持っているメソッド(関数)です。
- RemoveWidget関数は、引数(パラメータ)として1つのウィジェット(Widget)を受け取ります。
- 引数のWidgetは、削除したい特定のUI要素(ウィジェット)を示す変数です。
- RemoveWidget関数は、指定されたWidgetをPlayerUIから取り除きます。
この関数を使用することで、特定のプレイヤーのUIから特定のウィジェットを削除することができます。
例えば、ユーザーが削除ボタンを押すと、指定したウィジェット(例えば、メニューやボタンなど)がユーザーインタフェースから消えるようになります。

PlayerUIからMyUIを削除する理由
クリックすると開きます。
PlayerUIからMyUIを削除するのは、特定のプレイヤーのUIから特定のUI要素を取り除くためです。
詳細は以下のとおり。
このコードは、プレイヤーごとに個別のUI要素を表示する場合に使用されます。
具体的には、特定のプレイヤー(Message.Player)に関連付けられたPlayerUIというオブジェクトがあります。そして、そのPlayerUIから特定のUI要素(MyUI)を取り除くために、RemoveWidget関数を使用しています。
以下はコードの構造です:
- PlayerUIとMyUIの取得と代入:
- GetPlayerUI[Message.Player]は、特定のプレイヤーに関連付けられたPlayerUIオブジェクトを取得するための関数です。
- MaybeMyUIPerPlayer[Message.Player]は、特定のプレイヤーに関連付けられたUI要素(MyUI)を取得するための配列や辞書などのデータ構造です。
- 「:=」は、変数に値を代入するための演算子です。
- PlayerUI := GetPlayerUI[Message.Player]とMyUI := MaybeMyUIPerPlayer[Message.Player]の部分がそれに該当します。
- この行の目的は、特定のプレイヤーに関連したPlayerUIとMyUIを取得し、それぞれの変数に代入することです。
- PlayerUIからMyUIを削除する:
- PlayerUI.RemoveWidget(MyUI)の部分は、PlayerUIオブジェクトのRemoveWidget関数を使用して、特定のUI要素(MyUI)を取り除くために呼び出しています。
- これにより、PlayerUIオブジェクト内のUI要素からMyUIが削除されます。
- MaybeMyUIPerPlayer[Message.Player]をfalseに設定する:
- set MaybeMyUIPerPlayer[Message.Player] = falseの部分は、MaybeMyUIPerPlayer[Message.Player]という配列や辞書の要素をfalseに設定するためのコードです。
- これにより、UI要素(MyUI)が削除されたことを示すために、関連するデータ構造の値を変更しています。
このコードの目的は、特定のプレイヤーに関連したPlayerUIから特定のUI要素を削除し、関連するデータ構造の値を更新することです。これにより、プレイヤーごとのUIの動的な変更やリセットが可能になります。
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}の詳細
クリックすると開きます。
DeleteUI(Message: widget_message): void =
# プレイヤーのUIと個別のUIを取得し、それぞれをPlayerUIとMyUIに代入する
if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
# PlayerUIからMyUIを削除する
PlayerUI.RemoveWidget(MyUI)
# MaybeMyUIPerPlayer[Message.Player]をfalseに設定する
if(set MaybeMyUIPerPlayer[Message.Player] = false) {}
上記のコードは、MaybeMyUIPerPlayer
という辞書のキーにMessage.Player
が存在する場合、その値をfalse
に設定するという意味です。
まず、MaybeMyUIPerPlayer
はキーと値のペアを持つデータ構造であり、キーを指定して値にアクセスすることができます。このコードでは、辞書のキーとしてMessage.Player
が使用されています。
Message.Player
はメッセージに含まれるプレイヤーを指す変数または値を表していると仮定します。
MaybeMyUIPerPlayer[Message.Player]
は、辞書MaybeMyUIPerPlayer
のキーMessage.Player
に関連する値を取得します。
そして、=
を使ってその値にfalse
を代入しています。
以下は上記のコードのステップを順に解説したものです:
MaybeMyUIPerPlayer
という辞書が存在すると仮定します。Message.Player
変数または値を使って、辞書MaybeMyUIPerPlayer
のキーを指定します。- もし辞書
MaybeMyUIPerPlayer
にキーMessage.Player
が存在する場合、その値をfalse
に設定します。
FindButtonUI&ActivateTrigger&LoadButtonStateの定義
(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!")
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
(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: ウィジェットの取得に失敗しました!")
このコードは、特定のウィジェットに関連付けられたボタンUIを検索し、トリガーをアクティブにしたり、ボタンの状態を読み込んだりするためのものです。
詳細な説明は以下のとおり。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
指定されたThisWidgetに関連するButtonUIを探索する: (ここからforループが始まります)
for (ThisButtonUI: ButtonUI):
ThisButtonUIに関連するウィジェットがマッチするか確認する:
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
マッチした場合:
if (ThisWidget = StaleWidget):
ButtonUIをオプション型で返す
return option{ThisButtonUI}
マッチするButtonUIが見つからない場合はfalseを返す
return false
この部分では、FindButtonUI
関数を定義しています。この関数は、指定されたThisWidget
に関連するボタンUIを探し、見つかった場合はオプション型で返します。
forループを使用して各ButtonUI
にアクセスし、関連するウィジェットがマッチするかどうかを確認します。
マッチした場合は、見つかったボタンUIをオプション型で返します。
マッチするボタンUIが見つからなかった場合は、false
を返します。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする:
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
シグナルの送信先にSendInstigatorが存在するかチェックする:
if (ThisSignalDestination.SendInstigator?):
プレイヤーを指定して関連するトリガーをアクティブにする:
ThisSignalDestination.TriggerToActivate.Trigger(Player)
プレイヤーを指定せずに関連するトリガーをアクティブにする:
ThisSignalDestination.TriggerToActivate.Trigger()
この部分では、ActivateTrigger
関数を定義しています。この関数は、指定されたプレイヤーに関連するトリガーをアクティブにするためのものです。
まず、ThisButtonUI
のButtonSignal_Send
をシグナルの送信先に設定します。その後、送信先にSendInstigator
が存在するかをチェックします。
存在する場合は、指定されたプレイヤーを使用して関連するトリガーをアクティブにします。
SendInstigator
が存在しない場合は、プレイヤーを指定せずに関連するトリガーをアクティブにします。
(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: ウィジェットの取得に失敗しました!")
この部分では、LoadButtonState
関数を定義しています。この関数は、特定のボタンUIの状態をロードし、それを対応するウィジェットに適用します。
まず、ThisButtonUI
のSaveButtonState
がオンになっているかをチェックします。オンの場合は、エージェントに関連するウィジェットを取得します。ウィジェットの有効状態をEnabledStateMap
から取得し、適用します。
また、ウィジェットの可視状態をVisibleStateMap
から取得し、適切な可視性を適用します。値に基づいて可視性を設定するため、case
文が使用されます。ウィジェットが取得できない場合は、エラーメッセージが表示されます。
これらの関数は、リファレンスコード内で使用される特定の操作を実行するためのものであり、ウィジェットの状態を管理したり、ボタンUIやトリガーとの連携を行ったりするためのものです。

(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
(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: ウィジェットの取得に失敗しました!")
上記のコードの最大の目的は、特定のウィジェットに関連付けられたボタンUIを検索し、トリガーをアクティブにしたり、ボタンの状態を読み込んだりすることです。
FindButtonUI
関数は、指定されたウィジェットと関連するボタンUIを探索するためのものです。- forループを使用して、各ボタンUIにアクセスし、関連するウィジェットがマッチするかどうかを確認します。
- マッチした場合は、そのボタンUIをオプション型で返します。マッチするボタンUIが見つからない場合は、
false
を返します。
ActivateTrigger
関数は、特定のボタンUIに関連するトリガーをアクティブにするためのものです。- 指定されたプレイヤーに関連するトリガーをアクティブにします。
- もしトリガーに
SendInstigator
が存在する場合は、指定されたプレイヤーを使ってトリガーをアクティブにします。 - 存在しない場合は、プレイヤーを指定せずにトリガーをアクティブにします。
LoadButtonState
関数は、特定のボタンUIの状態を読み込み、それを関連付けられたウィジェットに適用するためのものです。- ボタンの状態が保存されている場合は、関連付けられたウィジェットを取得します。
- ウィジェットの有効状態と可視状態を取得し、保存された状態に基づいてウィジェットに適用します。
これらのコードは、ボタンUIとそれに関連するウィジェットの状態管理やトリガーの操作を行うためのものです。
特定のボタンUIを見つけたり、トリガーをアクティブにしたり、ボタンの状態を読み込んだりするために使用されます。

【例】
想像してください、あなたがスマートホームのリモコンを使って部屋の照明を制御している状況です。
FindButtonUI
関数は、あなたが特定のボタンを見つけたいときに使えるかわいそうな助手です。- 例えば、「オン」ボタンがどのボタンで表示されているか知りたいとき、助手にお願いしてそのボタンを探してくれます。
- 助手がボタンを見つけたら、それを教えてくれます。見つからなかった場合は「見つかりませんでした」と教えてくれます。
ActivateTrigger
関数は、リモコンのボタンを押して関連する機器(例えば、照明のスイッチ)を操作するときに使える便利な機能です。- もしリモコンに「オン」ボタンがあって、それを押すと照明がつく場合、助手にお願いしてあなたが指定した「オン」ボタンを押してもらえます。
- もし特定の人(プレイヤー)がボタンを押す必要がある場合は、その人を指定してもOKです。
- ただし、その人がリモコンのボタンを押す能力を持っている必要があります。
LoadButtonState
関数は、過去の状態を復元するときに使える機能です。- 例えば、あなたがリモコンを一時的に置いていて、状態(ボタンの有効/無効、ボタンの表示/非表示)が保存されている場合、助手にお願いしてその状態を読み込んでくれます。
- 読み込んだ状態に基づいて、リモコンのボタンが有効化されたり、表示されたりします。
- もし過去にリモコンを使ったことがなかった場合や状態の読み込みが失敗した場合は、エラーメッセージが表示されます。
このコードは、ある意味で「パシリ」のような存在です。
例えば、特定のボタンを見つけるために手間を省いてくれたり、ボタンを押したり、過去の状態を復元したりする手間を助けてくれます。


FindButtonUI
関数くん、、、あすかにパシられて...かわいそうに。🥲

名前をFindButtonUI
(ButtonUIを探す)と名付けるなんて、、
人間として信じられないわ...!!
ちょっと待て・・・
僕は名付けてない...。

(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
(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: ウィジェットの取得に失敗しました!")
上記のコードを記述しなかった場合、次のような問題が起こる可能性があります:
- ボタンUIの検索の問題:
- 特定のウィジェットに関連付けられたボタンUIを見つけるための機能が欠落します。
- このため、ボタンUIを見つけるために手動で探す必要があります。
- トリガーのアクティブ化の問題:
- 特定のボタンUIに関連するトリガーをアクティブにする機能が欠落します。
- ボタンのクリックやタップなどのユーザーアクションに対して、トリガーが反応しない可能性があります。
- ボタンの状態管理の問題:
- 特定のボタンUIの状態を読み込み、それを関連付けられたウィジェットに適用する機能が欠落します。
- たとえば、ウィジェットの有効化や無効化、可視性の制御などが正しく行われず、ユーザーが期待する動作を得られない可能性があります。
これらの問題を回避するために、上記のコードのような機能を実装することは重要です。
それにより、特定のウィジェットと関連するボタンUIを効率的に見つけることができ、トリガーをアクティブにし、ボタンの状態を正しく管理することができます。

(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =の詳細
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
このコードは、ThisWidget
というウィジェットと関連するButtonUI
(ボタンのユーザーインターフェース)を探索するためのものです。
手順は以下のとおり。
for
ループを使って、すべてのButtonUI
オブジェクトに順番にアクセスします。- ループ内部で、
ThisButtonUI
に関連するウィジェットがマッチするかどうか確認します。 ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、特定のプレイヤー(ここではAgent
という名前のエージェント)に関連付けられたウィジェットを取得するためのコードです。- もしウィジェットが取得できた場合、そのウィジェットが
ThisWidget
と一致するかどうかを確認します。 - ウィジェットが一致した場合、
ThisButtonUI
をオプション型で返します(オプション型は、値が存在する場合はその値を返し、存在しない場合はヌル値を返すことができるデータ型です)。 - もしループ内でマッチする
ButtonUI
が見つからなかった場合、false
を返します。
つまり、この関数は指定されたウィジェットに関連するボタンを探し、見つかった場合は該当するButtonUI
オブジェクトを返し、見つからなかった場合はfalse
を返します。
【イメージ】
このコードは、あなたが特定のウィジェット(例えば、スマートフォンのアプリケーションの画面上のボタン)を操作したい場合に役立ちます。具体的には、そのウィジェットに関連するボタンを見つけるためのコードです。
考えてみてください。スマートフォンのアプリケーションを使っていると、画面上には様々なボタンが表示されますよね。
このコードは、指定したウィジェットに関連するボタンを見つけるために、それらのボタンを探索する役割を担っています。
この探索のための手順は、次のようになります。
- 最初に、あなたが指定したウィジェット(ThisWidget)に関連するボタンを見つけるための探索を始めます。
- コードは、ボタン(ButtonUIオブジェクト)を1つずつチェックします。まるであなたが一つずつスマートフォンのボタンを確認しているようなイメージです。
- チェックしているボタン(ThisButtonUI)に関連するウィジェットがマッチするか確認します。
- ウィジェットのマッチングのために、ボタンが特定のプレイヤー(Agent)に関連づけられたウィジェットを保持しているか確認します。
- もしマッチするウィジェットが見つかった場合、それがあなたが指定したウィジェット(ThisWidget)と一致するか確認します。
- もし一致した場合、つまり関連するボタンが見つかった場合、そのボタン(ThisButtonUI)を返します。
- もし探索中にマッチするボタンが見つからなかった場合、falseを返します。
つまり、このコードは、あなたが指定したウィジェットに関連するボタン(ButtonUI)を探し、見つかったら特定のボタンを返し、見つからなかった場合はfalseを返します。これにより、特定のウィジェットに関連するボタンを効率的に見つける手助けをしてくれます。
あなたが指定したウィジェットとは「あなたが指定したウィジェット」とは、プログラムやコードの中で特定のウィジェットを識別するためにユーザーが指定・選択したものを指します。
このコードでは、「ThisWidget」という名前のウィジェットが、ユーザーが指定したウィジェットとなります。
例えば、スマートフォンのアプリケーションを考えてみましょう。画面上には複数のウィジェットがありますが、このコードでは特定のウィジェットに関連するボタンを見つけたいときに、「ThisWidget」という特定のウィジェットを指定します。
この指定により、その特定のウィジェットに紐付いたボタンを効率的に見つけることができます。
具体的な例を挙げると、例えばスマホのホーム画面では、ユーザーが「電話」アプリケーションのウィジェットを指定したとします。
このコードを使うと、指定した「電話」アプリケーションのウィジェットに関連するボタン(例えば「発信」ボタンや「連絡先」ボタン)を見つけることができるのです。
これにより、特定のウィジェットに関連する操作を効率的に行うことができます。


ウィジェットも複数存在するから、さらに絞って見つけやすくするために「特定の」ウィジェットを選択するってことですね!
ウィジェットは通常、画面上に複数存在します。そのため、特定のウィジェットを選択することで、そのウィジェットに関連するボタンを見つけやすくなります。
特定のウィジェットを選択することで、プログラムやコードがそのウィジェットに注目し、それに関連する操作や情報を取得することができます。
例えば、特定のウィジェットがある特定のアプリケーションの設定画面である場合、そのウィジェットに関連するボタンを見つけるための検索範囲が狭まります。
具体的な例えとしては、スマートフォンのホーム画面を考えてみましょう。ホーム画面には複数のウィジェットが配置されていますが、あなたが「天気」アプリケーションのウィジェットに関連するボタンを探したい場合、まずは「天気」アプリケーションのウィジェットを特定する必要があります。
これにより、ホーム画面上の他のウィジェットには関心を持たず、効率的に「天気」アプリケーションの関連ボタンを見つけることができます。
特定のウィジェットを選択することは、操作の目的を明確化し、特定の機能や情報に絞り込むために非常に役立つ手法です。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =についての詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
は、特定のウィジェットに関連するボタンUIを検索するための関数です。
この関数は、以下の手順で動作します:
widget
という変数に格納された特定のウィジェットに関連するボタンUIを探索します。ButtonUI
という変数にそれぞれのボタンUIを順番に代入しながら、以下の処理を繰り返します。ThisButtonUI
のButtonWidgetPerPlayer
という属性を使って関連するウィジェットを取得します。- もし取得されたウィジェットが
ThisWidget
と一致している場合、それはウィジェットとボタンUIが関連していることを意味します。 - そのボタンUIをオプション型で返します(もし見つからなかった場合は、falseを返します)。
つまり、この関数は指定されたウィジェットに関連するボタンUIを見つけて返す役割を果たします。
widget型である理由
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui
内の ThisWidget
は、イベントを発生させたウィジェットを指定するための引数です。
この引数の型が widget
である理由は以下の通りです。
ウィジェットは、ユーザーインターフェースの一部として使用される要素です。ウィジェットはさまざまな種類(ボタン、テキストボックス、イメージなど)があり、それぞれ異なるプロパティや操作を持っています。
ThisWidget: widget
という引数の型が widget
となっている理由は、FindButtonUI
関数に渡されるウィジェットがどの種類のウィジェットでも受け入れるためです。つまり、どのタイプのウィジェットでも渡すことができます。
なぜなら、この関数では特定のウィジェットを探し出すために、与えられたウィジェットと関連するButtonUIを見つける必要があるからです。
つまり、どのウィジェットでも元になっているのが、このwidget
という引数の型ということですね。

例えば、ボタンをクリックしたときにそのボタンに関連するButtonUIを見つける場合、クリックしたボタンのウィジェット(型としては widget
)をこの関数に渡すことができます。
ThisWidget: widget
は単に与えられたウィジェットを指定するための引数であり、任意のタイプのウィジェットを受け入れることを意味しています。

そのボタンに関連するButtonUIとは
クリックすると開きます。
ButtonUIは、ユーザーがクリックなどのアクションを実行するために表示されるボタンのインターフェース(UI)の一部です。ボタンは、ユーザーが特定の操作を実行するために画面上で押すことができる要素であり、ButtonUIはそのボタンの外観や振る舞いを制御するための情報を持っています。
具体的には、ButtonUIは以下のような特性を持っています:
- ボタンのテキストやアイコン:
- ButtonUIは、ボタンに表示されるテキストやアイコンの情報を保持します。
- ユーザーがボタンを認識しやすいように、わかりやすいテキストや適切なアイコンを設定することができます。
- イベントハンドラ:
- ButtonUIは、ボタンがクリックされたときなどのイベントを処理するためのイベントハンドラ(関数)を関連付けることができます。
- イベントハンドラは、ボタンがアクションされたときに実行され、応答や処理を実行します。
- 外観とスタイル:
- ButtonUIは、ボタンの外観やスタイルを設定するための情報を持ちます。
- ボタンのサイズ、色、フォントなどのスタイル設定を制御することができます。
- これにより、アプリケーションのデザインに一貫性を持たせたり、ユーザーにとって使いやすいボタンの外観を提供したりすることができます。
ボタンをクリックしたときに関連するButtonUIを見つける場合、ボタンとButtonUIは基本的に同じものを指しています。
もっと具体的に説明すると、ボタンは、ユーザーが実際にインタラクションする要素であり、ButtonUIはそのボタンに関連する情報を持つインターフェースです。言い換えると、ButtonUIはボタンの特徴や設定を保持しており、ボタンに対する操作や処理のために使われます。
buttonui がoptionである理由
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
?
が buttonui
の前につけられていることは、buttonui
がオプション型を表すことを意味します。
オプション型は、値が存在するかどうかを表現するために使用されます。具体的には、値が存在する場合はその値を保持し、存在しない場合は「null」や「何もない」ということを示す特殊な値を持ちます。
このコードでは、関数 (Agent: agent).FindButtonUI
は、与えられた ThisWidget
に関連する ButtonUI
を探索し、見つかった場合はその ButtonUI
を返します。
ただし、見つからなかった場合には false
を返します。
?
がついていることで、関数の返り値がオプション型であることを示しています。
つまり、関数は ButtonUI
の値を返す場合と、false
を返す場合の2つの可能性があることを示しています。
オプション型を使うことで、関数の呼び出し元は関数の結果が ButtonUI
か false
かを正しく判断し、それに応じた処理を行うことができます。

(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonuiでfalseを記述しない理由
クリックすると開きます。
このコードでは、(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui
の戻り値の型がオプション型であり、初期値は明示的に指定されていません。代わりに、マッチする ButtonUI
が見つからない場合に false
が返されます。
初期値を指定せずに false
を返す理由は、おそらく関数の仕様に基づいています。この関数は主に ButtonUI
を探索するためのものであり、見つからなかった場合に false
を返しています。
ただし、仕様によっては ButtonUI
を返すか、見つからなかった場合は null
や他の特定の値を返すこともあり得ます。この場合、コード全体や関数のドキュメントを確認する必要があります。
したがって、このコードの場合、見つからなかった場合に false
を返すことが意図されていると考えられます。
このコードは、関数 (Agent: agent).FindButtonUI(ThisWidget: widget)
が定義されています。この関数は、引数 ThisWidget
に関連する ButtonUI
を探索するためのものです。
関数の戻り値の型 ?buttonui
はオプション型を表しています。オプション型は、値が存在しない可能性があることを示すための型です。
オプション型は値を持つ場合と持たない場合の2つの状態を取りうるため、初期値を指定せずに false
を返すことで「値が存在しない」状態を表現しています。
関数の中身を見てみましょう。この関数では、与えられた ThisWidget
と関連する ButtonUI
を探し出します。
まず、for
ループ内の ThisButtonUI
に対して順番に処理を行います。その中で、ThisButtonUI
に関連する ButtonWidgetPerPlayer
という特定のウィジェット(ボタン)が、与えられたエージェント(Agent
)に対してマッチするかどうかを確認します。
ここで使われている :=
は、代入と同時に値を評価する演算子です。StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、ThisButtonUI
の ButtonWidgetPerPlayer
辞書から Agent
に対応するウィジェットを StaleWidget
に代入します。
次に、ThisWidget
(関数の引数)と StaleWidget
を比較しています。もし一致した場合、つまり ThisWidget
が StaleWidget
と同じである場合、その ButtonUI
(ThisButtonUI
) をオプション型で返します。
しかし、マッチする ButtonUI
が見つからなかった場合は、ループから抜けて return false
となります。つまり、関数が false
を返すようになっています。
関数 (Agent: agent).FindButtonUI(ThisWidget: widget)
は、指定したウィジェットに関連するボタンを探し出すためのもの。
そして、関連するボタンが見つかれば、そのボタン情報を返す。
しかし、ボタンが見つからなかった場合は false
を返します。


値を返すか返さないのか最初の時点だとはっきりしないので、falseと記述しないということですね🌸
オプション型の戻り値を持つ関数は、呼び出された時点では明確に値を返すかどうかがわからないため、初期値を指定せずに返り値のタイプの一部として「値が存在しない」状態を表現します。このコードでは、見つかった場合には対応する値を返し、見つからなかった場合には false
を返すという仕組みになっています。
もしも初期値を false
に設定してしまうと、見つからなかった場合でも明示的に false
を返さなければなりません。しかし、このコードでは見つからなかった場合に値を返さないため、初期値の設定を省略しています。
この設計により、関数の呼び出し側で戻り値をチェックする際に特別な条件分岐を行わず、単純に false
の場合は見つからなかったと判断できます。
初期値を指定しないことによってコードが簡潔になり、可読性が向上することがあります。
for (ThisButtonUI: ButtonUI):の詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを探索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
この行は、ButtonUI
というデータ型の要素を順番に取り出して ThisButtonUI
という変数に代入するためのループです。
ループする際、ループ変数の名前(この例では ThisButtonUI
)が定義され、その後に :
が続いてデータ型名(この例では ButtonUI
)が指定されています。
これにより、ループを行うために ButtonUI
の要素が1つずつ順番に取り出され、ThisButtonUI
という変数に代入されてループの本体が実行されます。
ループ本文の中では、ThisButtonUI
を使って特定の処理を行うことができます。このコードの場合、ThisButtonUI
に関連するウィジェットと ThisWidget
の一致を確認しています。
つまり、この for
ループは、ButtonUI
の要素を順に取り出して ThisButtonUI
に代入し、その後の処理で ThisButtonUI
に関連するウィジェットと ThisWidget
の一致を確認しています。
もし一致した場合は、該当する ButtonUI
をオプション型で返し、一致しなかった場合は次の要素に進んでループを続けます。ループの最後まで一致する ButtonUI
が見つからなければ、最終的に return false
が実行されます。
つまり、この for
ループはリストやコレクションの要素を一つずつ順に処理する際に使用され、ループの本体で要素に対して特定の処理を行います。
例えるなら、空港の持ち物検査ですね。
ButtonUI
をリストやコレクションに例えると、それぞれの要素が旅行客の持ち物であり、for
ループは持ち物を一つずつ検査する作業になります。
持ち物検査の際、セキュリティスタッフが一つの持ち物をチェックし、チェック結果に基づいて特定の処理を行います。


このコードでも同じように、ThisButtonUI
という変数が一つの要素(持ち物)を表し、その検査結果に応じて処理が行われているということですね!
そうですね。
持ち物検査と同様に、このループはリストやコレクションなどのデータの全体を網羅的に処理するための手法です。

if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):の詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
この行は条件文を表しています。ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、ThisButtonUI
と関連するウィジェットを指し示しています。そして、その結果(この場合、ウィジェット)を StaleWidget
という変数に代入します。
:=
は、Python 3.8から導入された「セイウチ演算子(Walrus operator)」と呼ばれる新しい機能であり、変数に値を代入しながら条件を評価するために使用されます。
この行の意味は、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
を評価し、その結果が null
や None
でない場合に条件を満たすということです。つまり、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
が有効な値を持っている場合に条件文の中の処理が実行されます。
もし ThisButtonUI.ButtonWidgetPerPlayer[Agent]
が null
や None
のような値を持っている場合は、条件文の中の処理は実行されず、次の行に進みます。
この行は、コードの中で特定の条件を判断するためのものであり、条件によって実行される処理が異なる場合に使用されます。セイウチ演算子を使用することで、変数への代入と条件の判断を1つの行で行うことができます。
ButtonWidgetPerPlayer=プレーヤーごとのボタンウィジェット

エージェント(Agent)とは、プログラム内で特定の役割を持ち、動作するための要素のことです。例えば、ゲーム内のキャラクターがエージェントとなります。
それぞれのエージェントには、表示されるべきウィジェット(ボタン、テキストエリア、画像などのグラフィカルな要素)があります。例えば、ゲーム内のプレイヤー1とプレイヤー2にはそれぞれ独自のウィジェットが関連付けられます。
ButtonWidgetPerPlayer
という辞書は、エージェントをキー(識別子)として、それぞれのエージェントに関連付けられたウィジェットを値(関連付けられた情報)として持っています。つまり、エージェントが特定のウィジェットを持つような関係を作るために使用します。
そのため、ループ処理を行いながら、ButtonUI
配列の要素を順番に処理することで、各エージェントの対応するウィジェットを見つけ、取得することができます。例えば、最初のループでは ButtonUI
の最初の要素が処理され、それに関連するエージェントのウィジェットが ButtonWidgetPerPlayer
辞書から取得されます。
このようにして、プログラム内の各エージェントに対して適切なウィジェットを関連付けることができます。これにより、各エージェントが表示されるべきウィジェットを持ち、正しい情報が表示されるようになるのです。
【例】
このコードでは、ウィジェット(ボタンや画面の部品のこと)とそれに関連するボタンUIを検索しています。
例えば、あるボタンUIには次のような情報があるとします:
- ボタンのID: 1
- プレイヤーごとのボタンの対応関係:
- エージェント1: ウィジェット(ボタン)の値が10
- エージェント2: ウィジェット(ボタン)の値が20
- エージェント3: ウィジェット(ボタン)の値が30
そして、検索するウィジェットの値が20だとします。
この場合、コードは次の手順で動作します:
- 最初のループで、ボタンUIにはIDが1で、プレイヤーごとの対応関係があります。
if
文は、エージェントに対応するウィジェットの値を取得しています。- ここでは、エージェント2に対応するウィジェットの値20を取得します。
ThisWidget
の値(20)と、エージェント2のウィジェットの値(20)を比較します。- この例では一致するため、条件式は真となります。
- そして、ボタンUIがオプション型で返されます。
- つまり、エージェント2に関連するボタンUIが返されることになります。
以上が、このコードの動作の簡単な説明です。
ウィジェットの値とボタンUIの関連をチェックして、一致するものを見つけることが目的です。
ThisButtonUIについてThisButtonUI
は、特定のボタン(ウィジェット)に関連するボタンUI(ボタンの外見や機能などを管理するオブジェクト)を表しています。
この例では、ThisButtonUI
が次のように定義されています:
ThisButtonUI = ButtonUI(id=1, ButtonWidgetPerPlayer={
Agent1: Widget(value=10),
Agent2: Widget(value=20),
Agent3: Widget(value=30)
})
ThisButtonUI
はid
が1で、各プレイヤー(Agent1
、Agent2
、Agent3
)に対してのウィジェット(Widget
オブジェクト)の対応関係を持っています。
Widget
オブジェクトにはそれぞれ異なる値が設定されています(10、20、30)。
ThisButtonUI
は、特定のボタンに関する情報をまとめたオブジェクトとして使われることでしょう。
StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]
のコードは、ThisButtonUI
のButtonWidgetPerPlayer
というマップから、Agent
に関連するウィジェットを取得して、StaleWidget
に代入しています。
具体的に説明します。ButtonWidgetPerPlayer
はagent
をキーとして、対応するウィジェットを値として持つマップです。[Agent1 => widget1, Agent2 => widget2, ...]
のような形式です。
ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、ThisButtonUI
に関連するウィジェットのうち、Agent
に対応するウィジェットを取得するための式です。この式の結果が、StaleWidget
に代入されます。
上記のコードでは、特定のウィジェットを持つButtonUI
を検索するために使用されています。StaleWidget
とThisWidget
が一致する場合に、そのButtonUI
をオプション型として返すことができます。
プレイヤーに関連するウィジェットを取得し、StaleWidget に代入しているわけですね。

var ButtonWidgetPerPlayer : [agent]widget = map{}
【重要】for (ThisButtonUI: ButtonUI)の要素とコレクションについて
クリックすると開きます。
for (ThisButtonUI: ButtonUI)
は、ButtonUI
というクラスのインスタンスを要素として持つコレクションに対して、各要素を順番に取り出して処理するためのループです。
具体的な例を挙げながら説明します。仮に以下のようなButtonUI
のインスタンスが存在するとします。
button1 := buttonui{
ButtonText = "Button 1",
ButtonPosition = vector2{X = 10, Y = 20},
ButtonSize = vector2{X = 100, Y = 50},
ButtonStyle = 1,
RemovesUIOnClick = true,
SaveButtonState = false,
SizeToContent = false,
ButtonWidgetPerPlayer = map{ Agent1 => widget{} },
EnabledStateMap = map{ Agent1 => true },
VisibleStateMap = map{ Agent1 => true }
}
button2 := buttonui{
ButtonText = "Button 2",
ButtonPosition = vector2{X = 30, Y = 40},
ButtonSize = vector2{X = 80, Y = 30},
ButtonStyle = 2,
RemovesUIOnClick = false,
SaveButtonState = true,
SizeToContent = false,
ButtonWidgetPerPlayer = map{ Agent1 => widget{} },
EnabledStateMap = map{ Agent1 => true },
VisibleStateMap = map{ Agent1 => true }
}
上記のようなインスタンスが存在する場合、for (ThisButtonUI: ButtonUI)
ループは次のように実行されます。
ThisButtonUI
にbutton1
が代入されます。button1
に対してループ内の処理が実行されます。ThisButtonUI
にbutton2
が代入されます。button2
に対してループ内の処理が実行されます。
このように、ループはコレクション内の要素を順番に取り出し、ThisButtonUI
に代入します。
各要素に対してループ内の処理が実行されます。コレクション内の要素がなくなるまでこのプロセスが繰り返されます。

ButtonUIに含まれる要素について
クリックすると開きます。
ButtonUIの要素は以下のとおり。
ButtonText
(String):- ボタンの表示テキスト
ButtonPosition
(Vector2):- ボタンの位置を表す2Dベクトル
ButtonSize
(Vector2):- ボタンのサイズを表す2Dベクトル
ButtonStyle
(ButtonChoice_Int):- ボタンスタイルを表す値。
button_loud
、button_quiet
、button_regular
のいずれかのキーがあります。(値は数値として表される)
RemovesUIOnClick
(Logic):- ボタンをクリックしたときにUIを非表示にするかどうかを表す論理値
SaveButtonState
(Logic):- ボタンの状態を保存するかどうかを表す論理値
ButtonSignal_Recieve
(ButtonUI_UserOptions_Functions):- ボタンが受信するユーザーオプションの関数を表すオブジェクト
ButtonSignal_Send
(ButtonUI_UserOptions_Events):- ボタンが送信するユーザーオプションのイベントを表すオブジェクト
SizeToContent
(Logic):- コンテンツに基づいてボタンのサイズを調整するかどうかを表す論理値
ButtonWidgetPerPlayer
([Agent]Widget):- プレイヤーごとに関連付けられたウィジェットを保持する辞書(マップ)
EnabledStateMap
([Agent]Logic):- プレイヤーごとの有効状態を保持する辞書(マップ)
VisibleStateMap
([Agent]Logic):- プレイヤーごとの表示状態を保持する辞書(マップ)
これらの要素は、ボタンのテキスト、位置、サイズ、スタイル、動作、状態の管理など、ボタンUIの振る舞いと外観に関連する様々な機能を表現しています。

ThisButtonUI
は、与えられたウィジェット(ThisWidget
)に関連付けられた ButtonUI
オブジェクトを指します。
FindButtonUI
メソッドは、与えられたエージェント(Agent
)とウィジェット(ThisWidget
)をパラメータとして受け取ります。このメソッドは、 ButtonUI
の配列 ButtonUI
内からウィジェットを持つ ButtonUI
オブジェクトを探索します。
具体的な動作を見てみましょう。
ButtonUI
配列の各要素ThisButtonUI
に対して繰り返し処理を行います。ThisButtonUI
のButtonWidgetPerPlayer
辞書(マップ)から、与えられたAgent
に関連付けられたウィジェットを取得し、一時変数StaleWidget
に代入します。- もし
ThisWidget
とStaleWidget
が一致していた場合、つまり、与えられたウィジェットと関連するButtonUI
オブジェクトを見つけた場合、ThisButtonUI
をoption{}
オプション型の値でラップして返します。 - もしマッチする
ButtonUI
が見つからなかった場合は、false
を返します(option{}
オプション型ではなく、直接false
という値です)。
したがって、FindButtonUI
メソッドは、指定されたウィジェットに関連する ButtonUI
オブジェクトを検索し、見つかった場合はそれをオプション型で返し、見つからなかった場合は false
を返します。

StaleWidgetと名付けられた理由
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
StaleWidget
は、このコードで新しいウィジェットを表すための一時変数です。名前自体に特別な意味はありませんが、一時的に使用され、後で比較に使用されるため「Stale(古くなった)」という形容詞が付けられていると推測されます。
このコードでは、ThisButtonUI
内の各ウィジェットとThisWidget
の値を照合するために使用されます。一致するウィジェットを見つけると、それをStaleWidget
に代入します。そして、ThisWidget
とStaleWidget
の値を比較して一致するかどうかを確認します。
ただし、StaleWidget
という名前は一般的ではなく、わかりにくいと感じる場合もあります。プログラムを理解する上で大切なのは、変数名が明確かつ分かりやすくなることです。したがって、もしコードを変更できる場合は、より意味のある変数名(例:matchedWidget
など)を選択することをおすすめします。
ThisWidgetの意味
クリックすると開きます。
ThisWidget
は、CreateMyUI
関数内で使用されている一時的な変数です。
具体的には、ThisWidget
はButtonUI
配列内の各ボタンのウィジェットオブジェクトを表しています。CreateMyUI
関数は、ButtonUI
配列内の各ボタンに対してUIを作成し、その中に配置するウィジェットを作成するために使用されます。
ThisWidget
は、ButtonUI
内の各ボタンのウィジェットを表す変数です。CreateMyUI
関数の各ボタンに対して適切なButtonStyle
に基づいてウィジェットを作成し、それをThisWidget
に代入します。その後、ThisWidget
が対応するButtonUI.ButtonWidgetPerPlayer[Agent]
に代入されることになります。
要するに、ThisWidget
は現在処理中のボタンに関連するウィジェットオブジェクトを表しており、その後の処理で使用されます。
【例】
例えば、ButtonUI
配列に3つの要素があり、各要素は異なるウィジェットを持っています。
ButtonUI = [
buttonui{ButtonWidgetPerPlayer: {agent1: widget1, agent2: widget2}},
buttonui{ButtonWidgetPerPlayer: {agent1: widget3, agent2: widget4}},
buttonui{ButtonWidgetPerPlayer: {agent1: widget5, agent2: widget6}}
]
この場合、FindButtonUI
関数はThisWidget
が指定されたウィジェット(例えばwidget3
)と一致するButtonUI
を探し、オプション型で返します。
探索の過程を説明すると、ThisWidget
引数にwidget3
が渡された場合、次のステップが行われます。
ButtonUI
配列の最初の要素を処理します。
ThisButtonUI
はbuttonui{ButtonWidgetPerPlayer: {agent1: widget1, agent2: widget2}}
です。StaleWidget
はThisButtonUI.ButtonWidgetPerPlayer[Agent]
となり、StaleWidget
はFalse
となります(widget3
とは一致しない)。- 次の要素に進みます。
ButtonUI
配列の2番目の要素を処理します。
ThisButtonUI
はbuttonui{ButtonWidgetPerPlayer: {agent1: widget3, agent2: widget4}}
です。StaleWidget
はThisButtonUI.ButtonWidgetPerPlayer[Agent]
となり、StaleWidget
はwidget3
となります(widget3
と一致)。option{ThisButtonUI}
を返して終了します。
したがって、FindButtonUI
関数はwidget3
に関連するButtonUI
をオプション型で返します。
もしもThisWidget
と一致するウィジェットが見つからない場合は、false
を返します。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
ThisButtonUI
はButtonUI
配列内の各要素を示し、ThisWidget
はThisButtonUI
に関連するウィジェットを示しています。
ThisButtonUI
はループの各イテレーションでButtonUI
配列の要素を代表し、ThisWidget
はその要素に関連するウィジェットを示します。
ループ内の条件文では、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
とThisWidget
の比較が行われ、一致した場合にThisButtonUI
が返されます。
ThisButtonUI
とThisWidget
は同じButtonUI
要素に関連付けられたウィジェットを参照していることを意味します。

マッチ部分の詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
このコードのマッチ部分は、指定されたThisWidget
に関連するButtonUI
を検索する役割を果たします。
例えば、以下のような状況を考えてみましょう。
ButtonUI
配列には3つの要素があります。- 各要素には、ボタンが関連付けられているウィジェットがあります。
- 私たちが探しているのは、指定されたウィジェット
ThisWidget
と関連するButtonUI
です。
この場合、例として以下のようなButtonUI
配列を考えます。
ButtonUI = [
buttonui{ButtonWidgetPerPlayer: {agent1: widget1, agent2: widget2}},
buttonui{ButtonWidgetPerPlayer: {agent1: widget3, agent2: widget4}},
buttonui{ButtonWidgetPerPlayer: {agent1: widget5, agent2: widget6}}
]
これから、ThisWidget = widget3
と想定してみましょう。
コードのマッチ部分の意味をみていきます。
- まず、
for (ThisButtonUI: ButtonUI):
の部分では、ThisButtonUI
という変数がButtonUI
内の要素を一つずつ順番に代入されます。 - 最初のイテレーションでは、
ThisButtonUI
はbuttonui{ButtonWidgetPerPlayer: {agent1: widget1, agent2: widget2}}
になります。 - 次に、
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
の部分では、ThisButtonUI
に関連するウィジェットをStaleWidget
という一時的な変数に代入します。 - 最初のイテレーションでは、
StaleWidget
はwidget1
になります。 - その後、
if (ThisWidget = StaleWidget):
の部分では、ThisWidget
とStaleWidget
が一致するか確認します。 - 最初のイテレーションでは、
ThisWidget
とStaleWidget
は一致しません(widget3
とwidget1
は異なる)。 - マッチングが一致しなかった場合、次の要素に進みます。
- 2番目のイテレーションでは、このステップが繰り返されます。
上記の内容を繰り返しイテレーションすることで、指定されたThisWidget
と一致するButtonUI
が見つかるかどうか確認します。
最終的に、一致するButtonUI
が見つかった場合は、option{ThisButtonUI}
として返されます。
この場合、探しているThisWidget
がwidget3
であるため、2番目のButtonUI
が一致します。したがって、結果としてbuttonui{ButtonWidgetPerPlayer: {agent1: widget3, agent2: widget4}}
がオプション型で返されます。
もし一致するButtonUI
が見つからない場合は、false
が返されます。
ButtonWidgetPerPlayer[Agent]を記述する理由は、ThisButtonUIにはウィジェット以外のUIも含まれているからという理由について
クリックすると開きます。
はい、正しいです。ButtonUI
はウィジェット以外の要素も含まれる可能性があるため、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
のようにButtonWidgetPerPlayer
を使用して特定のエージェントに関連するウィジェットを取得しています。
ButtonUI
は複数のエージェントに関する情報を持っており、各エージェントに対して関連するウィジェットを持つことができます。
ButtonWidgetPerPlayer
は辞書やマップのようなデータ構造で、エージェントをキーとして対応するウィジェットを取得するために使用されます。
このため、ThisButtonUI.ButtonWidgetPerPlayer[Agent]
を使用して指定されたエージェント(Agent
)に関連するウィジェットを取得し、それをStaleWidget
として一時的に保持しています。
その後、ThisWidget
とStaleWidget
を比較して一致するかどうかを確認します。
この手法により、ButtonUI
内の要素がウィジェット以外の他の種類のUIを含んでいる場合でも、正しく指定されたウィジェットを検索することができます。

【重要】ThisWidget はStaleWidgetと一致しているか確かめる変数であるため、ThisButtonUIのウィジェットのみを表す変数といえる
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
ThisWidget
はStaleWidget
と一致しているかどうかを確認するための変数であり、ThisWidget
がStaleWidget
と一致する場合、そのThisButtonUI
に関連するウィジェットを示すことになります。
したがって、ThisWidget
はThisButtonUI
のウィジェットを表す変数と考えることができます。
ThisWidget := Message.Sourceの詳細
クリックすると開きます。
はい、上記のコードから推測すると、ThisWidget := Message.Source
がThisWidget
の定義です。
コードにおいて、HandleSelectedUIButton
関数の中で以下のように記述されています:
ThisWidget := Message.Source
この行は、ThisWidget
をMessage.Source
として定義しています。従って、if(ThisWidget = StaleWidget):
の行では、ThisWidget
はMessage.Source
の値を指します。
このコードでは、HandleSelectedUIButton
関数が呼び出されたとき、Message
オブジェクト内のSource
プロパティがThisWidget
に代入されます。その後、ThisWidget
は他の箇所で使用されるために利用されます。
return option~return falseの詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
詳細は以下のとおり。
return option{ThisButtonUI}
この部分は、ButtonUI
をオプション型(option
)で返している箇所です。
オプション型は、値の存在または不在を表現するためのデータ型です。具体的には、値が存在する場合はその値を表し、値が存在しない場合は null
や None
などを表します。
ここでは、ButtonUI
が見つかった場合にその値を返しています。ThisButtonUI
は見つかった ButtonUI
のオブジェクトです。関数の返り値として option{ThisButtonUI}
と書かれているため、 ThisButtonUI
を含んだオプション型の値が返されます。
return false
この部分は、マッチする ButtonUI
が見つからなかった場合に false
を返す箇所です。
false
は、ブール型の値であり、偽を表します。ここでは、関数の返り値として false
が返されます。これは、ButtonUI
が見つからなかったことを意味します。
つまり、この関数の振る舞いは、ThisWidget
に関連する ButtonUI
を見つけた場合は ThisButtonUI
をオプション型で返し、見つからなかった場合は false
を返すということです。
オプション型を使用することで、関数の返り値の有無を明示的に表現することができ、結果をチェックする際に便利です。

returnの詳細
クリックすると開きます。
(Agent: agent).FindButtonUI(ThisWidget: widget): ?buttonui =
# 指定されたThisWidgetに関連するButtonUIを検索する
for (ThisButtonUI: ButtonUI):
# ThisButtonUIに関連するウィジェットがマッチするか確認する
if (StaleWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
if (ThisWidget = StaleWidget):
# ButtonUIをオプション型で返す
return option{ThisButtonUI}
# マッチするButtonUIが見つからない場合はfalseを返す
return false
return
は、プログラム内の関数やメソッドからの結果や値を返すために使用されるキーワードです。
関数やメソッドが呼び出された時、その中で処理を実行して結果を得た後、その結果を呼び出し元に返す際に return
を使用します。
この場合の return
文は、関数 (Agent: agent).FindButtonUI(ThisWidget: widget)
の実装部分の終わりに置かれており、関数が返り値として返す値を指定しています。
return option{ThisButtonUI}
この行では、option{ThisButtonUI}
と書かれており、関数の返り値として ThisButtonUI
を含んだオプション型の値を返します。
つまり、ThisButtonUI
を見つけた場合はその値が返されます。
また、もし ThisButtonUI
を見つけられなかった場合は、次の行の return false
が実行され、関数は false
を返します。
return
文は関数やメソッド内で一度しか実行されないため、その行に到達するとそれ以降の処理は実行されません。つまり、該当する条件が満たされた場合、その直後の return
文が実行され、関数はその時点で終了して呼び出し元に戻ります。
このコードでは、(Agent: agent).FindButtonUI(ThisWidget: widget)
関数が与えられた ThisWidget
に関連する ButtonUI
を検索し、見つかった場合にはその ButtonUI
を返します。一方、見つからなかった場合には false
を返します。
この判断は、以下のロジックに基づいています:
- ループを使って、各
ButtonUI
オブジェクトに対して以下の処理を行う:
ThisButtonUI
に関連するウィジェットがマッチするか確認する。- もしマッチする場合、つまり
ThisWidget
がStaleWidget
と一致する場合、ThisButtonUI
をオプション型で返す。
- ループが終了したとき(つまり、全ての
ButtonUI
を調べた後)、マッチするButtonUI
が見つからなかったのであれば、false
を返す。
このようにロジックが設計されているため、return
文が使われています。
return option{ThisButtonUI}
:option{ThisButtonUI}
は、見つかったButtonUI
をオプション型でラップすることで、返り値としてそのButtonUI
を返すために使用されます。
return false
:false
は、見つかったButtonUI
が無かった場合に返される値です。
return
文を使うことで、関数が特定の値を返すことができます。関数が呼び出し元に結果を返すためには、どのような条件でどの値を返すべきかを判断し、それに基づいて return
文を適切な位置に配置する必要があります。
return文を使う傾向があるコードの特徴
クリックすると開きます。
return
文を使う傾向があるコードにはいくつかの特徴があります。
一般的な事例は以下のとおり。
- 関数が特定の結果や値を返す場合:
- 関数が特定の処理を行った結果や計算結果を返す場合には、
return
文が使用されます。 return
を使って関数が値を返すことで、呼び出し元でその結果を利用したり、他の処理に渡したりすることができます。
- 関数が特定の処理を行った結果や計算結果を返す場合には、
- 条件に基づいた終了条件がある場合:
- 関数が特定の条件を満たした場合に処理を終了し、結果を返す必要がある場合、
return
文が使用されます。 - たとえば、特定の値が見つかった場合や、エラーが発生した場合に、関数の実行を終了して値を返すことがあります。
- 関数が特定の条件を満たした場合に処理を終了し、結果を返す必要がある場合、
- 条件による制御フローの変更が必要な場合:
- 関数内の条件や制御フローに基づいて、特定の条件が満たされた場合に異なる値を返す必要がある場合に、
return
文が使用されます。 - たとえば、条件分岐やループの中で、ある条件が満たされた場合に直ちに処理を終了して特定の値を返す場合に使用されます。
- 関数内の条件や制御フローに基づいて、特定の条件が満たされた場合に異なる値を返す必要がある場合に、
これらは一般的なシナリオであり、return
文の使用例の一部です。return
文は、関数の実行を終了し、値を返すための重要な要素です。関数が結果を返す場合や特定の条件で処理を終了する場合には、適切に return
文を利用することが重要です。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =の詳細
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
if (ThisSignalDestination.SendInstigator?):
ThisSignalDestination.TriggerToActivate.Trigger(Player)
ThisSignalDestination.TriggerToActivate.Trigger()
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
このコードは、ThisButtonUI
(buttonui
型の変数)が持つActivateTrigger
というメソッドを表しています。
まず、ThisButtonUI
のButtonSignal_Send
をシグナルの送信先として設定します(ThisSignalDestination
という変数に格納します)。
次に、ThisSignalDestination
のSendInstigator
が存在するかどうかをチェックします。SendInstigator
は、トリガーの送信元(またはアクティブ化主体)です。
もしSendInstigator
が存在する場合は、指定されたPlayer
(プレイヤー)を引数として、関連するトリガー(TriggerToActivate
)をアクティブ化します。つまり、特定のプレイヤーを指定してトリガーをアクティブにします。
もしSendInstigator
が存在しない場合は、プレイヤーを指定せずに関連するトリガーをアクティブにします。つまり、どのプレイヤーに対しても有効なトリガーをアクティブにします。
このコードの目的は、ThisButtonUI
に関連するトリガーをアクティブ化することです。トリガーのアクティブ化には、特定のプレイヤーを指定するかどうかによって動作が変わります。
トリガーをアクティブ化することによって、特定のアクションやイベントがトリガーされます。具体的に何が起こるかは、コードの背後にあるトリガーの仕組みやシステムに依存します。このコードの詳細な動作や目的が不明なため、具体的な結果を示すことはできませんが、一般的な例を挙げると以下のようなものが考えられます:
例えば、ゲームの場合、トリガーのアクティブ化によって、プレイヤーキャラクターの特定のアクションやイベントが発生する可能性があります。
例えば、ボタンを押すとドアが開く、トリガーをアクティブにすると敵キャラクターが出現する、などです。
システムの種類やソフトウェアの仕様によっては、トリガーのアクティブ化によって条件や制御フローが変化し、別の処理が実行される場合もあります。
ActivateTrigger関数はプレイヤーを指定してトリガーをアクティブにするか、プレイヤーを指定せずにトリガーをアクティブにするかを判断し、対応する処理を行います。

(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =の詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
この行は、関数 (ThisButtonUI: buttonui).ActivateTrigger を宣言しています。
関数はボタンUIのインスタンス ThisButtonUI を引数 buttonui として受け取り、プレイヤーを引数 Player として受け取ります。
また、この関数は戻り値がないことを示す void というキーワードが使われています。
Triggerとプレイヤーの関係性│指定することでできること
クリックすると開きます。
Trigger()
メソッドは、ThisSignalDestination
内の TriggerToActivate
というトリガーオブジェクトのメソッドです。
この実装部分は提供されていないため、具体的な振る舞いやトリガーの定義方法は明確ではありませんが、一般的には以下のようなシナリオを想定できます。
- トリガーオブジェクト (
TriggerToActivate
) は、アクションやイベントの発生をトリガーするための情報を保持しています。 Trigger()
メソッドは、このトリガーオブジェクトに対して呼び出されます。- プレイヤー引数 (
Player
) が指定されている場合、トリガーオブジェクトはこのプレイヤーに対してアクションを実行します。- 具体的に何が行われるかはトリガーの実装に依存します。
- たとえば、プレイヤーキャラクターのジャンプをトリガーする場合、指定されたプレイヤーのキャラクターがジャンプするようなアクションが実行されるかもしれません。
- プレイヤー引数が指定されていない場合、トリガーオブジェクトは通常、デフォルトの動作を実行します。
- これは、プレイヤーに依存しない汎用的なアクションやイベントをトリガーする場合に使用されます。
- たとえば、ゲーム内の特定のエフェクトを再生する場合、プレイヤーに関係なくトリガーオブジェクトがエフェクトを再生する可能性があります。
プレイヤーを指定することで、そのプレイヤーが何かしたときにトリガーが発動するということですね。

プレイヤーを指定することで、そのプレイヤーが何か特定のアクションを実行したときにトリガーが発動するようになります。トリガーは、指定されたプレイヤーのアクションに関連して発生するイベントやアクションをトリガーするために使用されます。
具体的には、ActivateTrigger
関数内のコードの中で、ThisSignalDestination.TriggerToActivate.Trigger(Player)
が呼び出されており、TriggerToActivate
というトリガーオブジェクトが、指定されたプレイヤー (Player
) のアクションをトリガーする役割を担っています。
例えば、プレイヤーキャラクターがボタンを押したときにトリガーを発動させたい場合、そのボタンUIに関連するプレイヤーを指定することで、ボタン押下時にトリガーがアクティブになり、関連するイベントがトリガーされる可能性があります。
Agent と Playerの違い
クリックすると開きます。
Agent と Player はどちらも、ゲームの登場人物を表す型です。
しかし、Agent は、Player よりも一般的な概念です。
Agent は、ゲームのルールに従って行動する、ゲームの登場人物です。
一方、Player は、人間が操作する、ゲームの登場人物です。つまり、Player は Agent の一種です。
Agent は広い概念でのプレイヤーということですね。

「エージェント」は、「プレイヤー」という広い概念の一部として捉えることができます。
一般的に「エージェント」という用語は、人工知能や自律システムなどが内部状態や環境の情報に基づいて判断や行動を行うプログラムやシステムを指します。
一方、「プレイヤー」という用語は、ゲームやインタラクティブなシステムに参加する人間やユーザーを指すことが一般的です。
AIや自律システムのコンテキストでは、「エージェント」は「プレイヤー」として行動し、判断を下し、環境や他のエージェントと対話するよう設計されることがあります。
ただし、全てのプレイヤーはエージェントと考えることができますが、逆に言えば、全てのエージェントがプレイヤーを表すわけではなく、人間の参加とは関係のない非ゲームのコンテキストで動作することもあります。
ちなみに、agentでも成立します。

voidにしている理由
クリックすると開きます。
関数の戻り値が void
になっているのは、この関数が値を返さないことを示しています。
この特定の ActivateTrigger
関数は、ボタンUIのトリガーをアクティブにするために使用されますが、他の場所から値を得る必要はありません。この関数は単にアクティブ化の処理を行い、結果を返す必要がないからです。
あくまでも"アクティブ化"するための関数です。

ThisSignalDestination := ThisButtonUI.ButtonSignal_Sendの詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
は、ThisButtonUI
の ButtonSignal_Send
というプロパティを ThisSignalDestination
という変数に代入する行です。
この行の意味を詳しく解説するために、以下のような例を考えてみましょう。
ThisButtonUI = {
ButtonSignal_Send: SomeValue
}
この例では、ThisButtonUI
というオブジェクト(または構造体)があり、ButtonSignal_Send
というプロパティがあります。それには SomeValue
という値が設定されています。
したがって、ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
は以下の操作を行います。
ThisButtonUI
のプロパティButtonSignal_Send
を参照します。- 参照した値(
SomeValue
)を、新たに作成した変数ThisSignalDestination
に代入します。
つまり、この行の目的は ThisButtonUI
の ButtonSignal_Send
の値を取得し、それを ThisSignalDestination
に格納することです。
このような代入操作は、プログラムで変数に値を割り当てるために一般的に使用されます。あるオブジェクトや変数のプロパティやフィールドの値を取得して、それを別の変数に格納することができます。これにより、取得した値を後続の処理で使ったり、操作したりすることができます。
※なお、:=
は一部のプログラミング言語(例: Pythonの:=
)で変数の宣言と代入を同時に行うために使用される記号です。他の言語では =
だけで変数への代入が行われます。一般的に :=
はアサインメント(代入)演算子と呼ばれます。
ButtonSignal_Sendの詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
ButtonSignal_Send
は、ButtonUI_UserOptions_Events
クラスのインスタンスです。インスタンスとは、クラスの設計図に基づいて作られた実際のオブジェクトのことです。
このコードでは、ButtonSignal_Send
という変数に ButtonUI_UserOptions_Events
クラスのインスタンスを代入しています。つまり、ButtonSignal_Send
は ButtonUI_UserOptions_Events
クラスのオブジェクトとして利用できます。
ButtonUI_UserOptions_Events
クラスは、UIボタンの設定情報を管理するためのクラスです。
このクラスには、以下のような設定情報があります:
TriggerToActivate
(トリガーをアクティブ化する対象):- この設定情報は、トリガーが発生したときにアクティブ化すべき対象を指定します。
- 例えば、ボタンを押したときに別の動作を開始させる場合、その動作の対象を
TriggerToActivate
に指定します。
SendInstigator
(ボタンの作動元を送信するかどうか):- この設定情報は、ボタンがクリックされた際にその情報を送信するかどうかを指定します。
- 例えば、ユーザーがボタンを押したことを他の場所に通知したい場合、
SendInstigator
を有効にすることでその情報を送信することができます。
ButtonSignal_Send
変数は、ButtonUI_UserOptions_Events
クラスのオブジェクトを持つので、ButtonUI_UserOptions_Events
クラスで定義されたプロパティやメソッドにアクセスすることができます。
また、@editable
という指示が付いているため、このインスタンスの設定情報を編集することが可能です。
つまり、ButtonSignal_Send
は、ButtonUI_UserOptions_Events
クラスを元に作られたボタンのオブジェクトであり、そのボタンの動作や設定を管理するための変数として使用されます。

@editable
ButtonSignal_Send : ButtonUI_UserOptions_Events = ButtonUI_UserOptions_Events{}
ButtonUI_UserOptions_Eventsの定義
クリックすると開きます。
ButtonUI_UserOptions_Events := class<concrete>():
# トリガー/アクティブ化する対象
@editable TriggerToActivate: trigger_device = trigger_device{}
# UIボタンの作動元を送信するかどうか
@editable SendInstigator: logic = true
ButtonUI_UserOptions_Events := class<concrete>():
ButtonUI_UserOptions_Events
というクラス(オブジェクトの設計図)を作成します。class<concrete>
は、このクラスが具体的な実装を持つクラスであることを示しています。
# トリガー/アクティブ化する対象
@editable TriggerToActivate: trigger_device = trigger_device{}
TriggerToActivate
というプロパティ(変数)を宣言します。- このプロパティは、トリガーまたはアクティブ化する対象を示します。
@editable
は、このプロパティが外部から編集可能であることを示すアノテーション(注釈)です。trigger_device
は、TriggerToActivate
のデータ型を示しています。trigger_device{}
は、TriggerToActivate
の初期値として、trigger_device
の新しいインスタンスを生成することを意味します。
# UIボタンの作動元を送信するかどうか
@editable SendInstigator: logic = true
SendInstigator
というプロパティを宣言します。このプロパティは、UIボタンの作動元を送信するかどうかを示します。@editable
は、このプロパティが外部から編集可能であることを示すアノテーションです。logic
は、SendInstigator
のデータ型を示しています。- この場合、
logic
は真偽値(True
またはFalse
)を表すデータ型です。
- この場合、
true
は、SendInstigator
の初期値として真(True
)を設定することを意味します。
したがって、このコードは、ButtonUI_UserOptions_Events
クラスを定義し、トリガーやアクティブ化の対象を管理するための TriggerToActivate
プロパティと、UIボタンの作動元を送信するかどうかを管理するための SendInstigator
プロパティを持たせています。
これらのプロパティは外部から編集可能であり、適切な初期値が設定されています。
噛み砕くとこのコードは、ボタンの設定情報を管理するための "ButtonUI_UserOptions_Events" というクラスを定義しています。クラスは、オブジェクトの設計図のようなものです。
このクラスには、2つの設定情報(プロパティ)があります。
- "TriggerToActivate"(トリガーをアクティブ化するための対象)という設定情報
- 例えば、ボタンをクリックした時に何か別のアクションを起こしたい場合、そのアクションの対象を指定するための情報です。
- 例えば、ボタンを押したらビデオを再生する場合、そのビデオを "TriggerToActivate" に設定することができます。
- "SendInstigator"(ボタンの作動元を送信するかどうか)という設定情報
- 例えば、ボタンが誰によって押されたかを知りたい場合、その情報を送信するかどうかを指定するための情報です。
- もしも "SendInstigator" が有効になっていれば、ボタンが押された情報を他の場所に送信することができます。
このクラスでは、これらの設定情報を外部から編集できるようにするために、@editable
という指示を使っています。
このクラスのインスタンスを作成すると、実際のボタンオブジェクトが作られます。そのオブジェクトには、設定情報が含まれています。その後、作成したボタンオブジェクトに対して、それぞれの設定情報を個別に設定したり変更したりすることができます。
このように、クラスはオブジェクトを作成するための設計図であり、設計図に従ってオブジェクトを作成することで、プログラムの中で効率的に管理することができます。
ThisButtonUI.ButtonSignal_Send をシグナルの送信先とする(できる)理由
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
ThisButtonUI.ButtonSignal_Send
をシグナルの送信先とする理由は、ThisButtonUI
オブジェクトが ButtonUI_UserOptions_Events
クラスのインスタンスであり、そのクラス内で ButtonSignal_Send
を定義しているからです。
具体的には、ButtonUI_UserOptions_Events
クラスはボタンの設定情報を管理するためのクラスです。ButtonSignal_Send
はその設定情報の1つで、別のButtonUI_UserOptions_Events
クラスのオブジェクトを持つことができます。
コード上では、ButtonUI_UserOptions_Events
クラスを元に作られた ThisButtonUI
オブジェクトがあります。
そして、このオブジェクトの中にある ButtonSignal_Send
プロパティは、また同じ ButtonUI_UserOptions_Events
クラスのオブジェクトを持つことができます。
なので、ThisButtonUI.ButtonSignal_Send
はButtonUI_UserOptions_Events
クラスのオブジェクトを参照しており、シグナルの送信先として設定することができるのです。
例えば、「ボタンを押した時に何かアクションを発生させたい」という場合、ButtonUI_UserOptions_Events
クラスの ButtonSignal_Send
プロパティに他のオブジェクトを割り当てることで、そのオブジェクトに対してアクションを送ることができます。
この機能を使うことで、ボタンがクリックされた時に特定の処理を実行したり、他のオブジェクトにシグナルを送ることが可能になります。

ThisSignalDestination=シグナルの送信先の詳細
クリックすると開きます。
ThisSignalDestination
は、ThisButtonUI.ButtonSignal_Send
の値を一時的に保持するための変数ですが、具体的には「シグナルの送信先」を指し示す役割を果たしています。
ThisButtonUI
オブジェクトは、ボタンのユーザーインターフェースを表していると仮定します。その中には ButtonSignal_Send
という名前のプロパティがあり、このプロパティにはシグナルの送信先に関する設定情報が格納されています。
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
の行では、ButtonSignal_Send
の設定情報を ThisSignalDestination
変数にコピーしています。つまり、ThisSignalDestination
は ButtonSignal_Send
の設定情報を指し示す変数となります。
その後、ThisSignalDestination
を使ってシグナル送信先に関連するトリガーやプレイヤーを操作するためのメソッドを呼び出します。
具体的なメソッド名は提供されていないため、 ThisSignalDestination
の具体的な内容についてはこのコードだけでは判断できませんが、ThisSignalDestination
が「シグナルの送信先」と関連する情報を保持していることは確かです。
要するに、ThisSignalDestination
はコード内で「シグナルの送信先に関する情報」を一時的に保持するための変数であり、後続の処理でこの情報に基づいて関連する操作を行うために使用されます。

シグナルの送信先とは
クリックすると開きます。
想像してください、あなたが友人にメッセージを送りたいとします。その際、メッセージ送信先の友人を指定する必要がありますよね。この場合、友人がシグナルの送信先に相当します。
具体的には、以下のような手順が考えられます:
- あなたが友人の名前と一緒にメッセージを作成します。(メッセージはトリガーに相当)
- メッセージを送信するためのアプリやプラットフォームを開きます。(ThisButtonUIに相当)
- メッセージを送る際、送信先として特定の友人を選択します。(シグナルの送信先)
- 選択した友人に対して、作成したメッセージを送信します。(トリガーをアクティブにする)
この例では、メッセージ送信先の友人を「シグナルの送信先」と考えることができます。シグナルは、メッセージを送るための情報や命令を表し、送信先が指定されなければメッセージを友人に届けることができません。
同様に、コードの中でシグナルを送る際に「シグナルの送信先」は、そのシグナルが届くべきオブジェクトや要素を指定する役割を果たします。このようにして、シグナルが特定のトリガー(メソッドやイベント)をアクティブにし、関連する操作が実行されるのです。
if (ThisSignalDestination.SendInstigator?):の詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
if (ThisSignalDestination.SendInstigator?):
は、条件文の一部であり、この行では ThisSignalDestination
の中に SendInstigator
というプロパティが存在するかどうかをチェックしています。
以下で解説します。
ThisSignalDestination
:- この変数は、前の行で
ThisButtonUI.ButtonSignal_Send
の値が代入されており、シグナルの送信先に関する情報を保持しています。
- この変数は、前の行で
.SendInstigator?
:ThisSignalDestination
の中にSendInstigator
というプロパティが存在するかどうかをチェックしています。SendInstigator
は、シグナルの送信先オブジェクトが持つプロパティの一つです。- プログラム中でオブジェクトが持つプロパティは、そのオブジェクトの特定の属性や情報を表現します。
if
文:if
文は、指定された条件が真(true
)である場合に処理を実行します。条件が偽(false
)である場合には、処理はスキップされます。ThisSignalDestination.SendInstigator?
の条件が真(true
)である場合、条件文の中の処理が実行されます。?
はnull合体演算子と呼ばれ、SendInstigator
プロパティが存在する場合にはその値を返し、存在しない場合にはnull
を返します。
この条件文は、ThisSignalDestination
の中に SendInstigator
というプロパティが存在する場合のみ、条件文の中の処理が実行されることを意味しています。
つまり、シグナルの送信先にイベントの発生元の情報が存在するかどうかをチェックしているということですね。

コードの条件文 if (ThisSignalDestination.SendInstigator?)
は、ThisSignalDestination
に発生元の情報(SendInstigator
)が存在するかどうかを確認しています。
条件文では、SendInstigator
属性の有無を確認するために ?
を使用しています。ThisSignalDestination.SendInstigator?
が存在すれば(true
であれば)、条件は真となり、その下のブロックが実行されます。
この条件文は、特定のアクションや処理が発生元の情報を必要とする場合に使用されている可能性があります。もし SendInstigator
が存在する場合は、関連するトリガーを特定のプレイヤー(Player
)に関連付けてアクティブにするための処理を実行しているのでしょう。
【例】
例えば、あなたが友人に手紙を送る場合を考えてみましょう。
あなたは手紙を送るために以下の手順を実行します:
- 友人の住所を特定する(送信先の情報を設定する)
- 友人が発信元の情報を受け取るようにする(イベントの発生元の情報を設定する)
この場合、手紙を送る前に送信先の情報(友人の住所)を確認し、友人に手紙が誰から来たのかを識別するために、手紙に発信元の情報(あなたの名前や住所)を含めるかどうかをチェックする必要があります。
コードの条件文 if (ThisSignalDestination.SendInstigator?)
は、まさにこのような手紙の例における「発信元の情報(あなたの名前や住所)が存在するかどうかをチェックする」に相当します。

# UIボタンの作動元を送信するかどうか
@editable SendInstigator: logic = true
SendInstigatorの意味
クリックすると開きます。
SendInstigator
は、ButtonUI_UserOptions_Events
クラス内のプロパティ(属性)です。このプロパティは logic
型であり、初期値として true
が設定されています。
SendInstigator
は、UIボタンがトリガーされたときに、そのボタンの"発生源"(instigator)を送信するかどうかを制御するためのプロパティです。ここでの "instigator" は、ボタンが押された原因や関連するオブジェクトを指します。
UIボタンがトリガーされたとき、SendInstigator
が true
に設定されている場合、UIボタンのトリガー操作を受け取ったオブジェクト(通常はプレイヤー)が、関連するトリガーに対して情報を送信することができます。
この情報は、トリガーが実行されるときに利用されることがあります。
一方、SendInstigator
が false
に設定されている場合、UIボタンのトリガーが発生した際には、関連するトリガーが情報を受け取る際に、発生源に関する情報は含まれません。
このように、SendInstigator
プロパティを使用することで、UIボタンのトリガー操作を受け取ったオブジェクト(instigator)がトリガーの実行時に情報を送信するかどうかを制御することができます。

SendInstigator
は、UIボタンがクリックされたときに発生するイベントの中で、そのイベントの発生元(通常はプレイヤーやオブジェクト)を他のコードに伝えるための設定です。
例えば、ゲームのUIボタンがクリックされたときに、そのイベントが他のオブジェクトに伝達される場合を考えます。SendInstigator
が true
に設定されている場合、そのイベントが発生したオブジェクト(プレイヤーやボタンそのもの)が、他のコードに伝えられます。
このような機能は、例えば「どのプレイヤーが特定のボタンをクリックしたかを判定したい」などの場合に有用です。
SendInstigator
を有効にすることで、イベントを受け取る側のコードが、イベントの発生元を特定して処理することができます。
つまり、イベントを起爆させた発生元を特定できるわけですね。

SendInstigator
を有効にすることで、イベントを受け取る側のコードが、イベントの発生元(例えば、ボタンをクリックしたプレイヤーなど)を特定して処理することができます。
具体的な例を考えましょう。あるゲームの場合、UIボタンがクリックされると、爆発する効果を発生させたいとします。このとき、SendInstigator
を有効にすると、イベントを受け取る側のコードが、ボタンをクリックしたプレイヤーが誰であるかを特定することができます。
つまり、SendInstigator
を使用することで、爆発効果を発生させる際に、正確にどのプレイヤーがボタンをクリックしたかを知ることができます。
これにより、特定のプレイヤーにのみ爆発効果を適用する、または異なるプレイヤーに異なる効果を適用するなど、より具体的な制御が可能になります。
ThisSignalDestination.TriggerToActivate.Trigger(Player)の詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
このコードでは、ThisSignalDestination.TriggerToActivate.Trigger(Player)
は特定のトリガーをアクティブにするために使用されています。
以下に解説します:
ThisSignalDestination
は変数またはフィールドであり、ThisButtonUI.ButtonSignal_Send
に該当します。- つまり、
ThisSignalDestination
はThisButtonUI
のButtonSignal_Send
プロパティ(またはフィールド)を参照しています。
- つまり、
ThisSignalDestination.TriggerToActivate
はThisSignalDestination
内の別のプロパティ(またはフィールド)であり、特定のトリガーを指します。TriggerToActivate
プロパティ(またはフィールド)は、Trigger オブジェクト(トリガーオブジェクト)を参照しています。Trigger(Player)
は、Trigger
オブジェクトのTrigger
メソッド(関数)を呼び出しています。- このメソッドは、引数として
Player
を受け取るようになっています。
- このメソッドは、引数として
つまり、上記のコードは次のような流れで処理が行われます:
ThisSignalDestination
をThisButtonUI
のButtonSignal_Send
に設定します。ThisSignalDestination
のSendInstigator
プロパティ(またはフィールド)が存在するかを確認します。- もし存在する場合は、プレイヤーを引数としてトリガーをアクティブにします。
ThisSignalDestination
のTriggerToActivate
プロパティ(またはフィールド)の指すトリガーをアクティブにします。- ここでは、プレイヤーを引数としてトリガーを実行します。
- もし
SendInstigator
が存在しない場合、プレイヤーなしでトリガーをアクティブにします。
このコードの目的は、ボタンの UI(ユーザーインターフェース)からトリガーをアクティブにすることです。プレイヤーに関連するトリガーがある場合は、プレイヤーを引数としてトリガーを実行します。そうでない場合は、プレイヤーなしでトリガーを実行します。
前提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
Trigger関数の詳細
クリックすると開きます。
Trigger関数は、特定のアクションをトリガーするために使用される関数です。
詳細は以下のとおり。
UEFNTrigger関数の詳細:
- 関数名: Trigger
- 引数: Agent (エージェント)
- 返り値の型: void (なし)
関数の使用方法:Trigger<public>(Agent:agent)<varies><transacts><no_rollback>
Trigger<public>
:- この関数は公開(public)アクセス修飾子を持つことを示します。
- 他のコードやオブジェクトからこの関数にアクセスできるようにします。
(Agent:agent)
:- Agentという名前の引数を受け取ります。
- この引数はトリガーを実行したエージェント(プレイヤーなど)を示します。
<varies>
:- 引数のデータタイプは多様なものであることを示します。
- Agent引数の値は様々なタイプのデータを受け取ることができます。
- 具体的なデータタイプはコンテキストによって異なります。
<transacts>
:- この関数はトランザクションを実行することを示します。
- トランザクションは、一連の処理をまとめて実行し、途中のエラーが発生した場合にはロールバック(処理の取り消し)が行われる仕組みです。
<no_rollback>
:- この関数はトランザクションの途中でのロールバックを許可しないことを示します。
- つまり、一度トリガーが実行された場合、そのトリガーを取り消すことはできません。
関数の説明:
Trigger関数は、特定のデバイスやオブジェクトに対して、エージェントが行ったアクションをトリガーするために使用されます。
エージェント(プレイヤーなどの操作主体)を引数として受け取ります。
この関数を使用する際には、トリガーを実行するために特定のエージェントを要求する場合があります(たとえば、特定のエージェントのみでデバイスをトリガーしたい場合など)。
プログラミングにおける例:
以下は仮想的なコード例です。
Trigger(public) (Agent agent) {
// トリガーの処理を記述する
// このデバイスを指定したエージェントでトリガーした場合に実行されるコード
}
上記のコードでは、Trigger
関数が public
(公開)として宣言され、Agent
というエージェントを引数として受け取ります。関数の中には、トリガーが実行された際に行われる処理が記述されます。
この関数を使用すると、特定のデバイスやオブジェクトに対してエージェントを指定してトリガーを実行できます。
これにより、特定の条件や要件を満たしたエージェントだけがアクションをトリガーできるように制御できます。

ThisSignalDestination.TriggerToActivate.Trigger()の詳細
クリックすると開きます。
(ThisButtonUI: buttonui).ActivateTrigger(Player: player): void =
# ThisButtonUIのButtonSignal_Sendをシグナルの送信先とする
ThisSignalDestination := ThisButtonUI.ButtonSignal_Send
# シグナルの送信先にSendInstigatorが存在するかチェックする
if (ThisSignalDestination.SendInstigator?):
# プレイヤーを指定して関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger(Player)
# プレイヤーを指定せずに関連するトリガーをアクティブにする
ThisSignalDestination.TriggerToActivate.Trigger()
ThisSignalDestination.TriggerToActivate.Trigger()
は、関連するトリガーをアクティブにするための処理を行うコードです。
具体的に説明すると、以下のような動作をします。
ThisSignalDestination
は、ThisButtonUI.ButtonSignal_Send
を参照しています。- つまり、シグナルの送信先を表しています。
ThisSignalDestination.TriggerToActivate
は、ThisSignalDestination
に関連付けられたトリガーの参照を示しています。- つまり、このコードの目的は、関連するトリガーをアクティブにすることです。
Trigger()
は、トリガーをアクティブにするための関数です。- この関数を呼び出すことで、トリガーが発動します。
したがって、ThisSignalDestination.TriggerToActivate.Trigger()
は、ThisSignalDestination
に関連するトリガーをアクティブにするための処理を実行することを意味します。
このコードにおいては、ThisSignalDestination.SendInstigator?
の結果によって、プレイヤーを指定してトリガーをアクティブにする場合と、プレイヤーを指定せずにトリガーをアクティブにする場合があります。具体的な動作は、ボタンUI(ThisButtonUI
)やそれに関連するトリガーの仕様に依存します。
まとめると、ThisSignalDestination.TriggerToActivate.Trigger()はプレイヤーを指定せずにトリガーをアクティブにします。

まとめ
今回はUIボタンのVerse(4)について解説しました。
お疲れさまでした🍵
長かったですね汗
僕のTwitterアカウントです。-
-
【UEFN】UIボタンの作り方(5ページ目)│Verse解説の続き
続きを見る