

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

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

もくじ
UIボタンの作り方(3ページ目)│Verse解説の続き
CreateMyUIの定義
CreateMyUI(Agent : agent) : canvas =
for(CurrButtonUI : ButtonUI):
case(CurrButtonUI.ButtonStyle):
1 =>
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
2 =>
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
3 =>
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
_ =>
Print("~ERROR: ButtonStyle integer over/under-flow")
CanvasArray := ReturnCanvasSlots(Agent)
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
return MyInteractableButtons
クリックすると開きます。
CreateMyUI(Agent : agent) : canvas =
# ButtonUIの各要素に対してループを実行する
for(CurrButtonUI : ButtonUI):
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが2の場合
2 =>
# ThisButtonUIをbutton_quiet型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが3の場合
3 =>
# ThisButtonUIをbutton_regular型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
このコードは、CreateMyUI
という関数を定義しています。
以下に各行の意味や目的を記述します。
CreateMyUI(Agent : agent) : canvas =
:CreateMyUI
という関数を定義し、引数と戻り値の型を指定しています。
for (CurrButtonUI : ButtonUI):
:ButtonUI
内の各要素に対してループ処理を行います。
case (CurrButtonUI.ButtonStyle):
:CurrButtonUI
のButtonStyle
の値によって処理を分岐させます。
1 =>
:ButtonStyle
が1の場合の処理です。ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
:button_loud
型のThisButtonUI
を作成し、デフォルトテキストにCurrButtonUI
のButtonText
を設定します。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
:ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。
if (set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
:CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
2 =>
:ButtonStyle
が2の場合の処理です。ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
:button_quiet
型のThisButtonUI
を作成し、デフォルトテキストにCurrButtonUI
のButtonText
を設定します。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
:ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。
if (set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
:CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
3 =>
:ButtonStyle
が3の場合の処理です。ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
:button_regular
型のThisButtonUI
を作成し、デフォルトテキストにCurrButtonUI
のButtonText
を設定します。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
:ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。
if (set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
:CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
_ =>
:ButtonStyle
が1, 2, 3以外の場合の処理です。Print("~ERROR: ButtonStyle integer over/under-flow")
:- エラーメッセージを出力します。
CanvasArray := ReturnCanvasSlots(Agent)
:- エージェントに対応するキャンバススロットの配列を取得します。
MyInteractableButtons : canvas = canvas: Slots := CanvasArray
:MyInteractableButtons
をcanvas
型として作成し、Slots
にCanvasArray
を設定します。
return MyInteractableButtons
:MyInteractableButtons
を返します。
この関数の目的は、エージェントに対応するUI要素を作成してキャンバスに配置し、それを返すことです。ボタンUIの各要素に対して指定されたスタイルに応じて処理を分岐し、各ボタンのテキストやクリック時のイベントハンドラを設定します。
最後に、エージェントに対応するキャンバススロットを取得して、それをキャンバスに配置して返します。
※イベントハンドラとは、イベントが発生した際に呼び出される処理のこと。
概要このコードは、与えられたエージェントに対してUI(ユーザーインターフェース)を作成するための関数です。
具体的には以下のとおり。
ButtonUI
の各要素に対してループを実行します。ButtonUI
は、ボタンの詳細な情報を含むデータ構造です。
- 各ボタンのスタイルに応じて処理を分岐します。
ButtonStyle
は、ボタンのスタイルを示す数値です。
- ボタンスタイルに応じたボタンUIオブジェクトを作成します。
button_loud
、button_quiet
、button_regular
はボタンの種類を表すデータ型です。ThisButtonUI
は、新しく作成されたボタンUIオブジェクトを指します。- ボタンのデフォルトテキストには、
ButtonText
というプロパティの値が設定されます。
- 作成されたボタンUIオブジェクトがクリックされた場合に、
HandleSelectedUIButton
関数が呼び出されるように設定します。- ボタンUIオブジェクトの
OnClick()
メソッドを使用して、クリックされたときの処理を登録します。
- ボタンUIオブジェクトの
- エージェントをキーとして、ボタンUIオブジェクトを
ButtonWidgetPerPlayer
にセットします。ButtonWidgetPerPlayer
は、各エージェントに対して割り当てられたボタンUIオブジェクトを格納する辞書です。
- ボタンスタイルが1、2、3以外の場合は、エラーメッセージが出力されます。
- エージェントに対応するキャンバススロットの配列を取得します。
ReturnCanvasSlots
関数を呼び出して、エージェントに割り当てられたキャンバスのスロットの配列を取得します。
MyInteractableButtons
というキャンバスオブジェクトを作成し、スロットにキャンバス配列を設定します。MyInteractableButtons
を返します。
つまり、この関数は与えられたエージェントに対して、指定されたボタンUIのスタイルに基づいてボタンを作成し、それらをキャンバスオブジェクトに配置して返すものです。

canvasクラスの詳細
クリックすると開きます。
Canvasクラスは、ウィジェットを任意の位置に配置するためのコンテナウィジェットです。
キーワード:コンテナ、ウィジェット、スロット
Inheritance Hierarchy(継承階層):
- Canvasクラスは、widgetクラスから派生しています。
- widgetクラスは、プレーヤーの画面上に描画されるすべてのUI要素の基本クラスです。
Data(データメンバ):
- Slots(スロット):
- キャンバスの子ウィジェットの配列です。
- ウィジェットの初期化時にのみ使用され、Add/RemoveWidgetによって変更されません。
Functions(関数):
- AddWidget:
- 新しい子スロットをキャンバスに追加します。
- GetParentWidget:
- ウィジェットの親ウィジェットを取得します。
- 親が存在しない場合(このウィジェットがplayer_uiに含まれていない場合や、自体がルートウィジェットの場合など)、失敗します。
- GetRootWidget:
- このウィジェットをplayer_uiに追加したウィジェットを取得します。
- ルートウィジェットは自体を返します。
- このウィジェットがplayer_uiに含まれていない場合は失敗します。
- GetVisibility:
- 現在のウィジェットの表示状態を返します。
- IsEnabled:
- ウィジェットがプレーヤーによって対話的に変更可能かどうかを示す真偽値を返します。
- RemoveWidget:
- 指定されたウィジェットを含むスロットを削除します。
- SetEnabled:
- プレーヤーがこのウィジェットと対話できるかどうかを有効または無効にします。
- SetVisibility:
- ウィジェットを非表示にするか表示するかを設定しますが、player_uiから自体を削除しません。
つまり、Canvasクラスは、ウィジェットを配置するためのコンテナであり、AddWidgetやRemoveWidgetなどのメソッドを使って子ウィジェットを管理します。
また、ウィジェット間の階層関係に関する情報を取得するための便利なメソッドも提供しています。
Canvasクラスを使うときCanvas型は、UI要素を自由に配置する必要がある場合に使用されます。例えば、ゲームの画面上に複数のウィジェットを配置し、それらを任意の位置やサイズで配置したい場合にCanvas型が使用されます。
Canvas型は、他のレイアウト制約が不要な場合や、ウィジェット間の相対的な位置関係を厳密に制御する必要がある場合に特に有用です。ウィジェットの配置において柔軟性と制御性を求める場合に、Canvas型を使用することが適しています。
例えば、HUD(ヘッドアップディスプレイ)やゲームのインベントリ画面など、固定された位置に複数の要素を配置するケースでCanvas型はよく使用されます。
また、ドラッグアンドドロップやアニメーションといったインタラクティブな要素が必要な場合にもCanvas型が適しています。
Class型の利点は、似たようなオブジェクトを簡単に作成できることです。
ボタンのスタイルごとに異なるクラスを作成することで、それぞれのボタンの特性や振る舞いをカプセル化し、コードをより管理しやすくします。

今回forループを実行する理由
クリックすると開きます。
ループ処理は、同じまたは類似の操作を複数回繰り返すために使用されます。
この場合、ButtonUIの各要素に対してループ処理を行っている理由は、異なるスタイルを持つ複数のボタンを作成するためです。
ループ処理のフローは以下のとおり。
- まず、ButtonUIの各要素を順番に参照しながらループを実行します。
- 各要素のButtonStyleの値によって処理を分岐します。
- ButtonStyleの値に応じて、適切なスタイルのボタンを作成します。
- 例えば、ButtonStyleが1の場合は"button_loud"というスタイルのボタンを作成し、ButtonStyleが2の場合は"button_quiet"というスタイルのボタンを作成します。
- 作成されたボタンに対して、デフォルトテキストの設定やクリック時の動作(HandleSelectedUIButton関数の呼び出し)などの設定を行います。
- 最後に、ButtonWidgetPerPlayerにエージェントをキーとして作成したボタンをセットします。
このようにループ処理を行うことで、ButtonUIの要素ごとに異なるスタイルのボタンを作成し、それぞれのボタンに適切な設定を行うことができます。また、将来的にButtonStyleの種類が増えた場合でも、処理を追加するだけで対応できるようになります。
agentにoptionを使わない理由
クリックすると開きます。
agentにオプションの表記を使わない理由は、おそらくこの関数がプレイヤーに関連するUIを作成するためのものであり、プレイヤーが存在しない場合には意味がないからだと思われます。
もしagentにオプションの表記を使用すると、nullで渡された場合やエージェントが存在しない場合に対応する処理を追加する必要があります。しかし、この関数は明示的にプレイヤーに関連するUIを作成するためのものであるため、プレイヤーがいることを前提としています。
したがって、この関数ではエージェントの存在が前提条件であり、オプションの表記を使わないことで、プレイヤーが存在しない場合には関数が適切に動作しないようになっています。
for(CurrButtonUI : ButtonUI):の論理
クリックすると開きます。
このコードは、ButtonUIの各要素に対してループを実行しています。
for(CurrButtonUI : ButtonUI):
このループは、ButtonUIというリスト(またはコレクション)の中の各要素を順番に取り出して、変数CurrButtonUIに代入します。ループ内の処理は、取り出したCurrButtonUIごとに実行されます。
次に、CurrButtonUIのButtonStyleの値によって処理を分岐しています。
case(CurrButtonUI.ButtonStyle):
CreateMyUI(Agent : agent) : canvas =
# ButtonUIの各要素に対してループを実行する
for(CurrButtonUI : ButtonUI):
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが2の場合
2 =>
# ThisButtonUIをbutton_quiet型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが3の場合
3 =>
# ThisButtonUIをbutton_regular型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
case(CurrButtonUI.ButtonStyle)
は、変数 CurrButtonUI.ButtonStyle
の値によって分岐する制御構造です。この計算式は、CurrButtonUI
というボタンのスタイル(ButtonStyle)の値によって、異なる処理を行います。
具体的に説明すると、CurrButtonUI.ButtonStyle
は整数(integer)の値です。
以下の3つのケースがあります。
- もし
CurrButtonUI.ButtonStyle
の値が1
の場合、ThisButtonUI
という Loud(大きな音量)のボタンが作られます。- このボタンにはクリックイベントの処理が登録されます。
CurrButtonUI.ButtonWidgetPerPlayer[Agent]
という場所にThisButtonUI
を設定します。
- もし
CurrButtonUI.ButtonStyle
の値が2
の場合、ThisButtonUI
という Quiet(静かな音量)のボタンが作られます。- このボタンにはクリックイベントの処理が登録されます。
CurrButtonUI.ButtonWidgetPerPlayer[Agent]
という場所にThisButtonUI
を設定します。
- もし
CurrButtonUI.ButtonStyle
の値が3
の場合、ThisButtonUI
という Regular(通常の音量)のボタンが作られます。- このボタンにはクリックイベントの処理が登録されます。
CurrButtonUI.ButtonWidgetPerPlayer[Agent]
という場所にThisButtonUI
を設定します。
- 上記以外の値の場合、
- エラーメッセージ "ButtonStyle integer over/under-flow" が表示されます。
最後に、エージェントに対応するキャンバススロットの配列を取得し、MyInteractableButtonsというcanvas型のUI要素を生成します。このUI要素のSlotsには、先ほど取得したCanvasArrayが設定されます。
最終的に、関数はMyInteractableButtonsを返します。
Caseの詳細
クリックすると開きます。
「case」は、プログラムの中で特定の値に基づいて分岐するための構文です。複数の値の比較を行い、一致する値に対応する処理を実行します。
以下に、初心者向けにわかりやすく解説します。
例えば、ある変数「GuardStateVariable」の値に基づいて、ガードの状態に応じた動作を実行したい場合を考えましょう。
それぞれのケースごとに異なる処理が必要です。
以下が、ガード状態を表す「GuardStateVariable」とそれに応じた処理を実行する例です。
case(GuardStateVariable):
idle_state =>
RunIdleAnimation()
SearchPlayerCharacter()
harvest_state =>
GatherResources()
alert_state=>
RunAlertAnimation()
PlayAlertSound()
DisplayAlertUIElement()
TargetPlayerCharacter()
attack_state =>
RunAttackAnimation()
DisplayAttackUIElement()
TargetPlayerCharacter()
AttackPlayerCharacter()
_ =>
RunPatrolAnimation()
SearchPlayerCharacter()
SearchResources()
上記の例では、「GuardStateVariable」という変数の値によって処理が分岐します。例えば、ガードの状態が"harvest_state"であれば、"GatherResources()"という関数が実行されます。
各ケースは次のようになっています。
- "idle_state"の場合:
- アイドルアニメーションを再生し、プレイヤーキャラクターを探索します。
- "harvest_state"の場合:
- リソースを収集します。
- "alert_state"の場合:
- アラートアニメーションを再生し、アラートの音を再生し、アラートのUI要素を表示し、プレイヤーキャラクターをターゲットにします。
- "attack_state"の場合:
- 攻撃アニメーションを再生し、攻撃のUI要素を表示し、プレイヤーキャラクターをターゲットにして攻撃します。
- それ以外の場合:
- パトロールアニメーションを再生し、プレイヤーキャラクターとリソースを探索します。
また、最後のデフォルトのケース "_ =>" は、どのケースにも一致しない場合の処理を示します。この場合、パトロールアニメーションを再生し、プレイヤーキャラクターとリソースを探索するという処理が実行されます。
「case」は、プログラムの中で特定の値に基づいて条件分岐を行い、それぞれのケースに応じた処理を実行するための便利な構文です。

ButtonUI の具体的な要素の内容
クリックすると開きます。
forループの for (CurrButtonUI : ButtonUI)
の部分では、ButtonUI
という配列やリストに含まれる各要素を順番に取り出して、それぞれを CurrButtonUI
という名前の変数に代入して処理を行います。
つまり、このループによって ButtonUI
内の要素が1つずつ取り出され、CurrButtonUI
に代入されています。その後の処理では、CurrButtonUI
のプロパティ(ButtonStyle
、ButtonText
、ButtonWidgetPerPlayer
など)に基づいて異なる処理が行われます。
具体的な例を考えてみましょう。もし ButtonUI
が以下のようなリストだとします。
ButtonUI = [
{ButtonStyle: 1, ButtonText: "OK", ButtonWidgetPerPlayer: {}},
{ButtonStyle: 2, ButtonText: "Cancel", ButtonWidgetPerPlayer: {}},
{ButtonStyle: 3, ButtonText: "Submit", ButtonWidgetPerPlayer: {}}
]
この場合、ループが最初の要素 {ButtonStyle: 1, ButtonText: "OK", ButtonWidgetPerPlayer: {}}
を取り出して処理します。CurrButtonUI
の値はこれになります。その後、ButtonStyle
の値が 1 の場合の処理ブロックが実行されます。
次に、2番目の要素 {ButtonStyle: 2, ButtonText: "Cancel", ButtonWidgetPerPlayer: {}}
が取り出されます。再び、CurrButtonUI
の値がこの要素になります。この場合、ButtonStyle
の値が 2 であるため、2番目の処理ブロックが実行されます。
最後に、3番目の要素 {ButtonStyle: 3, ButtonText: "Submit", ButtonWidgetPerPlayer: {}}
が取り出されます。同じく、CurrButtonUI
の値がこの要素になります。ButtonStyle
の値が 3 のため、3番目の処理ブロックが実行されます。
つまり、このループでは、ButtonUI
リスト内のすべての要素に対して同じ処理を繰り返し実行します。
各要素のプロパティ値に応じて条件分岐などの処理を行っていると考えられます。
ButtonStyleの値はもとからCurrButtonUIに格納されている
クリックすると開きます。
CurrButtonUI
はButtonUI
の各要素を表す変数です。ButtonStyle
の値はCurrButtonUI
に格納されています。
ButtonUI
はループの前で宣言されていないため、おそらくButtonUI
はあらかじめ定義されたデータ構造やオブジェクトの配列(またはコレクション)を指しているものと推測されます。
従って、CurrButtonUI
はその配列の要素であり、各要素はButtonStyle
フィールドを持っています。
ループを通じてButtonUI
にアクセスし、それぞれの要素のButtonStyle
の値をチェックしています。case(CurrButtonUI.ButtonStyle):
は、各要素のButtonStyle
の値に応じて処理を分岐するために使用されています。
1 =>~Print("~ERROR: ButtonStyle integer over/under-flow")の詳細
クリックすると開きます。
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが2の場合
2 =>
# ThisButtonUIをbutton_quiet型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが3の場合
3 =>
# ThisButtonUIをbutton_regular型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
上記のコードは、エージェントのためにインタラクティブなボタンUIを作成する関数です。
以下、コードの解説をします。
for(CurrButtonUI : ButtonUI):
:
ButtonUI
の各要素に対してループを実行します。CurrButtonUI
は、ButtonUI
の要素を順番に参照するための変数です。
case(CurrButtonUI.ButtonStyle):
:
CurrButtonUI
のButtonStyle
の値によって処理を分岐します。
1 =>
:
ButtonStyle
が1の場合の処理です。ThisButtonUI
という変数をbutton_loud
型として作成します。ThisButtonUI
のデフォルトテキストにCurrButtonUI
のButtonText
を設定します。ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
2 =>
:
ButtonStyle
が2の場合の処理です。ThisButtonUI
という変数をbutton_quiet
型として作成します。ThisButtonUI
のデフォルトテキストにCurrButtonUI
のButtonText
を設定します。ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
3 =>
:
ButtonStyle
が3の場合の処理です。ThisButtonUI
という変数をbutton_regular
型として作成します。ThisButtonUI
のデフォルトテキストにCurrButtonUI
のButtonText
を設定します。ThisButtonUI
がクリックされたときにHandleSelectedUIButton
関数を呼び出すように設定します。CurrButtonUI
のButtonWidgetPerPlayer
にエージェントをキーとしてThisButtonUI
をセットします。
_ =>
:
ButtonStyle
が1、2、3以外の場合のデフォルトの処理です。- エラーメッセージを出力します。
CanvasArray := ReturnCanvasSlots(Agent)
:
- エージェントに対応するキャンバススロットの配列を取得します。
MyInteractableButtons : canvas = canvas: Slots := CanvasArray
:
MyInteractableButtons
という変数をcanvas
型として作成します。Slots
に先ほど取得したCanvasArray
を設定します。
return MyInteractableButtons
:
MyInteractableButtons
を返します。
この関数の目的は、ButtonUI
の各要素をループで処理し、それぞれのButtonStyle
に基づいて相応のボタンUIを作成することです。作成したボタンUIは、関数の最後で作成したキャンバスに配置され、それが返されます。
ボタンUIの作成の流れは以下のとおり。
ButtonUI
の要素を順番に処理するButtonStyle
の値に応じて、適切な種類のボタンUIを作成- ボタンUIのデフォルトテキストを設定
- ボタンがクリックされたときに実行される関数を設定
- ボタンUIをエージェントに関連付ける
- キャンバスに配置する
- キャンバスを返す
このようにして、関数を呼び出すことで、指定されたエージェントのために適切なボタンUIを作成できます。
1 => ThisButtonUI := の論理
クリックすると開きます。
下記のコードは、CreateMyUI
関数内でUI要素を生成するための処理を示しています。
以下では、指定のコードセクションを詳しく説明します。
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
このコードセクションは、CurrButtonUI
という変数に格納されているボタンのスタイルに応じて処理を分岐させています。
ボタンスタイルが1の場合の処理を解説します。
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
:
button_loud
クラスのオブジェクトThisButtonUI
を作成しています。button_loud
は、派生クラスの一種であり、特定のスタイルが適用されたテキストボタンを表します。DefaultText
というデータメンバーを設定し、CurrButtonUI.ButtonText
の値を表示するデフォルトテキストとして設定しています。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
:
ThisButtonUI
の.OnClick()
という関数を呼び出し、ボタンがクリックされたときに実行するイベントにHandleSelectedUIButton
関数を登録しています。- つまり、ボタンがクリックされたときに
HandleSelectedUIButton
関数が呼び出されるようになります。
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
:
CurrButtonUI.ButtonWidgetPerPlayer[Agent]
は、Agent(エージェント)をキーとしてButtonWidgetPerPlayer辞書内の要素を取得します。- この要素に
ThisButtonUI
を設定し、エージェントに対応するボタンを格納します。 set
キーワードは値の代入を行うためのものであり、条件式(if文)が成立する場合にのみ処理が実行されます。
このコードセクションでは、ボタンスタイルが1の場合にbutton_loud
クラスのオブジェクトを作成し、デフォルトテキストやクリック時のイベントハンドラを設定します。
また、エージェントに対応するボタンをButtonWidgetPerPlayer
辞書に格納しています。
StringToMessage<localizes>(String : string):message = "{String}"
@editable var ButtonText : string = ""
button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}で{}を使っている理由
クリックすると開きます。
button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
は、オブジェクトの初期化およびプロパティの設定を行っています。button_loud
は特定のスタイルが適用されたボタンを表すクラスまたは構造体のインスタンスです。
プログラミングの多くの言語では、新しいオブジェクトを作成するときに()
またはnew
キーワードを使用します。しかし、一部のプログラミング言語では、オブジェクトの初期化とそのプロパティの設定をより直感的に行うために、{}
で囲まれた初期化子(initializer)を使用する方法が提供されています。
button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
は、button_loud
クラスまたは構造体の新しいインスタンスを作成し、その初期値を設定しています。
DefaultText
というプロパティには、StringToMessage(CurrButtonUI.ButtonText)
の値が割り当てられます。
{}
を使用した初期化子を使うことで、複数のプロパティ値を簡潔に指定できます。また、特定の順序でプロパティを指定する必要もなくなります。
この例では、button_loud
のインスタンスを作成し、そのDefaultText
プロパティにCurrButtonUI.ButtonText
の値を設定しています。
このような初期化方法は、可読性やコードの簡潔さを向上させるのに役立ちます。
定義を思い出そうStringToMessage<localizes>(String : string):message = "{String}"
@editable var ButtonText : string = ""
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}で「CurrButtonUI」を使用する理由
クリックすると開きます。

CurrButtonUI
は、既存のボタンオブジェクトを参照しています。
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
のコードは、CurrButtonUI
から取得したButtonText
を使って新しいボタンオブジェクトThisButtonUI
を作成し、そのデフォルトテキストとして設定しています。
このようにして新しいボタンオブジェクトを作成する理由は、おそらく既存のボタンオブジェクトとは異なるスタイルや振る舞いを持つbutton_loud
型のボタンを作成するためです。
CurrButtonUI
のテキストを利用することで、新しいボタンでも同じテキストが表示されるようになります。
したがって、CurrButtonUIはテキストの取得元として使用され、それを使って新しいボタンオブジェクトを作成するために必要とされているのです。

ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
のコードでは、既存のボタンオブジェクト CurrButtonUI
から ButtonText
の値を取得して、新しいボタンオブジェクト ThisButtonUI
のデフォルトテキストとして設定しています。
なぜ CurrButtonUI
を使用して ButtonText
を取得する必要があるのか、理由をより具体的に解説します。
- ボタンオブジェクト間の情報の共有:
CurrButtonUI
は既存のボタンオブジェクトを参照しており、それにはButtonText
などのプロパティが含まれています- このプロパティには特定のテキストが設定されています。
- 新しいボタンオブジェクト
ThisButtonUI
は、同じテキストを持つ必要があります。 - そのために、
CurrButtonUI.ButtonText
を使用してButtonText
の値を取得し、新しいボタンオブジェクトに設定しています。
- 柔軟性とメンテナンス性の向上:
CurrButtonUI
を介してButtonText
を取得することで、ボタンのテキストが変更される場合にも自動的に反映されます。- つまり、既存のボタンのテキストを変更するだけで新しいボタンにもその変更が反映されるため、コード全体を修正する必要がありません。
したがって、「CurrButtonUI.ButtonText」を使ってテキストを取得することで、既存のボタンオブジェクトの情報を共有し、ボタンのテキスト変更に対する柔軟性とメンテナンス性を向上させているのです。
これにより、コードの効率性と一貫性が向上し、開発プロセスが円滑化します。
参考StringToMessage<localizes>(String : string):message = "{String}"
@editable var ButtonText : string = ""
DefaultTextに代入する目的
クリックすると開きます。
DefaultText
に代入する目的は、button_loud
クラスの初期化時に表示されるデフォルトのテキストを設定するためです。これは、ボタンが最初に表示されたときに、ユーザーに表示するデフォルトのメッセージを指定するために使用されます。
このスクリプトは、ThisButtonUI
という名前のbutton_loud
型のオブジェクトを作成しています。その後、DefaultText
プロパティにCurrButtonUI
のButtonText
を設定しています。これにより、CurrButtonUI
のButtonText
に指定されたテキストが、ボタンが初期化されたときに表示されるようになります。
なぜデフォルトテキストを代入する必要があるかというと、ボタンのテキストはユーザーが任意のタイミングで変更できる場合があるからです。
例えば、ボタンのラベルを動的に変更する必要がある場合や、異なるユーザーごとに異なるデフォルトテキストを表示する必要がある場合などが考えられます。
したがって、DefaultText
に代入を行うことで、初期化時にボタンに表示されるデフォルトのテキストを簡単に指定できるようになります。ユーザーが明示的にテキストを変更しない場合、DefaultText
が表示されることになります。
詳細は以下の記事を参照してください。
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}の意味
クリックすると開きます。
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
この行は、button_loud型の新しいオブジェクト ThisButtonUI を作成しています。
{}内のブロックは、button_loudオブジェクトの初期化時に設定するプロパティです。
DefaultTextプロパティには、CurrButtonUIのButtonTextという値が代入されています。
StringToMessageは、テキストをメッセージオブジェクトに変換するための関数であると推測されます。
ThisButtonUIに代入しなければならない理由
クリックすると開きます。
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
ThisButtonUI
は、ループ内で作成される新しいボタンオブジェクトを参照するための変数です。
この変数に新しいボタンオブジェクトを代入することで、後続の処理で使用できるようになります。

例えば、ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
の行では、クリックイベントが発生したときに呼び出すべき関数を設定しています。
ThisButtonUI
が代入されていない場合、どのボタンオブジェクトがクリックイベントを持つべきかが分からなくなってしまいます。
また、CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI
の行では、Agent
をキーとしてCurrButtonUI
のプロパティにThisButtonUI
をセットしています。
このようにすることで、Agent
に対応するボタンを特定できます。ThisButtonUI
が代入されていない場合、正しいボタンオブジェクトを特定できなくなります。
つまり、ThisButtonUI
に代入することで、新しいボタンオブジェクトを変数として利用し、適切な操作や参照ができるようになるのです。


後続のコードで処理するために、適切な変数に値を代入する必要があるわけですね🌸
ThisButtonUI
に値を代入することで、その変数を介して新しいボタンオブジェクトにアクセスできます。
例えば、ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
では、ThisButtonUI
に代入したボタンオブジェクトのクリックイベントに対して、HandleSelectedUIButton
という関数を設定しています。
同様に、CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI
では、ThisButtonUI
に代入したボタンオブジェクトを、CurrButtonUI
のプロパティButtonWidgetPerPlayer
の中でAgent
キーに関連付けています。
これらの処理を実行するためには、事前に適切な変数に値を代入する必要があります。
そのため、ThisButtonUI := ...
の形式でThisButtonUI
に値を代入しています。
これにより、後続の行でThisButtonUI
を介してボタンオブジェクトにアクセスできるようになります。
StringToMessage<localizes>(String : string):message = "{String}"
buttonui := class<concrete>():
@editable var ButtonText : string = ""
ThisButtonUI に直接文字列を代入できるが・・・
クリックすると開きます。
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
の場合、button_loud
型のThisButtonUI
オブジェクトを作成し、そのDefaultText
プロパティにCurrButtonUI.ButtonText
を代入しています。
直接文字列をThisButtonUI
に代入することもできますが、DefaultText
プロパティを使用することで、ボタンのテキストを柔軟に設定できるようになります。
DefaultText
が存在しない場合、デフォルトのテキストが表示されない可能性がありますが、それによって発生する問題は使用環境や要件によって異なります。
例えば、ボタンに明示的なテキストがない場合、ユーザーがボタンの目的や機能を把握するのに困るかもしれません。
また、ボタンのデザインによっては、テキストが空の場合に表示されるデフォルトのテキストやデザイン要素があるかもしれません。
デフォルトテキストを指定する理由
クリックすると開きます。
デフォルトテキストは、ボタンが初めて表示されたときに表示されるデフォルトのテキストです。
通常、ユーザーがボタン上でテキストを変更することができるようになっていますが、初期状態ではデフォルトのテキストが表示されます。
このような場合に、DefaultTextというプロパティを使用して初期テキストを設定することができます。
デフォルトテキストを変更することで、最初にボタンが表示されたときに表示されるテキストを設定することができます。

buttonui := class<concrete>():
@editable var ButtonText : string = ""
@editable var ButtonPosition : vector2 = vector2{}
@editable var ButtonSize : vector2 = vector2{X := 475.0, Y:= 80.0}
# 'ButtonStyle' key: {button_loud = 1, button_quiet = 2, button_regular = 3}
@editable var ButtonStyle : buttonchoice_int = 3
@editable var RemovesUIOnClick : logic = true
# Saves the state the button is in even after exiting. Example: Hiding a button, exiting the ui, and then opening the ui will still have that button hidden
@editable SaveButtonState : logic = false
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)は何をしている?
クリックすると開きます。
この行は、ThisButtonUIオブジェクトがクリックされたときにHandleSelectedUIButton関数が呼び出されるように設定しています。
おそらく、ボタンがクリックされた際の処理をHandleSelectedUIButton関数で行うために、OnClick()イベントに対して購読(Subscribe)しているのだと推測されます。
button_loudクラスの詳細
クリックすると開きます。
button_loud
クラスは、大きくて派手なスタイルが適用されたテキストボタンを表すクラスです。ゲーム開発エンジンであるUnreal EngineのUIフレームワークで使用されます。
以下に、button_loud
クラスの技術的な詳細を説明します。
widget
クラスから派生しています:
widget
は、プレーヤーの画面上に描画されるすべてのUI要素の基本クラスです。
text_button_base
クラスを継承しています:
text_button_base
は、カスタムのメッセージ文字列を表示するボタンの基本クラスです。
メンバー(データおよび関数):
button_loud
クラスには、データメンバーと関数が含まれています。
データメンバー:
データメンバーの名前、型、および説明を以下に示します。
DefaultText
: 表示するテキスト。- ウィジェットの初期化時にのみ使用され、
SetText
で変更されません。
関数:
代表的な関数とその説明を以下に示します。
GetParentWidget
:- ウィジェットの親ウィジェットを取得します。
- 親が存在しない場合(例:このウィジェットがplayer_uiにない場合や自体がルートウィジェットの場合)は失敗します。
GetRootWidget
:- このウィジェットをplayer_uiに追加したウィジェットを取得します。
- ルートウィジェットは自身を返します。
- このウィジェットがplayer_uiにない場合は失敗します。
GetText
:- ウィジェットに現在表示されているテキストを取得します。
GetVisibility
:- 現在のウィジェットの表示状態(可視性)を取得します。
IsEnabled
:- プレーヤーがこのウィジェットを対話的に変更できる場合はtrueです。
OnClick
:- ボタンがクリックされたときに発生するサブスクライブ可能なイベントです。
SetEnabled
:- プレーヤーがこのウィジェットと対話できるかどうかを有効または無効にします。
SetText
:- ウィジェットに表示されるテキストを設定します。
SetVisibility
:- 自身を含むplayer_uiから削除せずにウィジェットを表示または非表示にします。
以上が、button_loud
クラスの概要です。このクラスを使用することで、大きくて派手なスタイルが適用されたテキストボタンを作成し、表示や対話を制御することができます。
ちなみに、loudは「大きい」「うるさい」などの意味があります。

button_quietクラスの詳細
クリックすると開きます。
button_quiet
クラスは、控えめなスタイルが適用されたテキストボタンを表します。このクラスもUnreal EngineのUIフレームワークで使用されます。
以下に、button_quiet
クラスの技術的な詳細を説明します。
widget
クラスから派生しています:
widget
は、プレーヤーの画面上に描画されるすべてのUI要素の基本クラスです。
text_button_base
クラスを継承しています:
text_button_base
は、カスタムのメッセージ文字列を表示するボタンの基本クラスです。
メンバー(データおよび関数):
button_quiet
クラスには、データメンバーと関数が含まれています。
データメンバー:
データメンバーの名前、型、および説明を以下に示します。
DefaultText
: ユーザーに表示するテキストです。- ウィジェットの初期化時のみ使用され、
SetText
によって変更されません。
- ウィジェットの初期化時のみ使用され、
関数:
代表的な関数とその説明を以下に示します。
GetParentWidget
: ウィジェットの親ウィジェットを取得します。親が存在しない場合(例:このウィジェットがplayer_uiにない場合や自体がルートウィジェットの場合)は失敗します。GetRootWidget
: このウィジェットをplayer_uiに追加したウィジェットを取得します。ルートウィジェットは自身を返します。このウィジェットがplayer_uiにない場合は失敗します。GetText
: ウィジェットに現在表示されているテキストを取得します。GetVisibility
: 現在のウィジェットの表示状態(可視性)を取得します。IsEnabled
: プレーヤーがこのウィジェットを対話的に変更できる場合はtrueです。OnClick
: ボタンがクリックされた時に発生するサブスクライブ可能なイベントです。SetEnabled
: プレーヤーがこのウィジェットと対話できるかどうかを有効または無効にします。SetText
: ウィジェットに表示されるテキストを設定します。SetVisibility
: 自身を含むplayer_uiから削除せずにウィジェットを表示または非表示にします。
以上が、button_quiet
クラスの概要です。このクラスを使用することで、控えめなスタイルが適用されたテキストボタンを作成し、表示や対話を制御することができます。
quietには、「静かな」「落ち着いた」という意味があります。

button_regularクラスの詳細
クリックすると開きます。
button_regular
クラスは、通常のスタイルが適用されたテキストボタンを表します。これもUnreal EngineのUIフレームワークで使用されます。
以下に、button_regular
クラスの技術的な詳細を説明します。
widget
クラスから派生しています:
widget
は、プレーヤーの画面上に描画されるすべてのUI要素の基本クラスです。
text_button_base
クラスを継承しています:
text_button_base
は、カスタムのメッセージ文字列を表示するボタンの基本クラスです。
メンバー(データおよび関数):button_regular
クラスには、データメンバーと関数の両方があります。
データメンバー:
以下に、データメンバーの名前、型、および説明を示します。
DefaultText
: ユーザーに表示するテキストです。ウィジェットの初期化時のみ使用され、SetText
によって変更されません。
関数:
以下に、代表的な関数とその説明を示します。
GetParentWidget
: ウィジェットの親ウィジェットを取得します。親が存在しない場合(例:このウィジェットがplayer_uiにない場合や自体がルートウィジェットの場合)は失敗します。GetRootWidget
: このウィジェットをplayer_uiに追加したウィジェットを取得します。ルートウィジェットは自身を返します。このウィジェットがplayer_uiにない場合は失敗します。GetText
: ウィジェットに現在表示されているテキストを取得します。GetVisibility
: 現在のウィジェットの表示状態(可視性)を取得します。IsEnabled
: プレーヤーがこのウィジェットを対話的に変更できる場合はtrueです。OnClick
: ボタンがクリックされた時に発生するサブスクライブ可能なイベントです。SetEnabled
: プレーヤーがこのウィジェットと対話できるかどうかを有効または無効にします。SetText
: ウィジェットに表示されるテキストを設定します。SetVisibility
: 自身を含むplayer_uiから削除せずにウィジェットを表示または非表示にします。
以上が、button_regular
クラスの概要です。このクラスを使用することで、通常のスタイルが適用されたテキストボタンを作成し、表示や対話を制御することができます。
regularには、「通常」「いきつけ」などの意味があります。

記号「=>」とは
クリックすると開きます。
=>
は、プログラム内でスイッチケース (switch case) 文の一部として使用されています。スイッチケース文は、特定の値に基づいて異なる処理を実行するための制御構造です。
具体的には、case
の右側にある値と一致した場合に、それに続くブロックの処理が実行されます。
次に、具体的な例を使って説明します。以下のコードを考えてみます:
switch (value) {
case 1 =>
// valueが1と一致した場合の処理
break;
case 2 =>
// valueが2と一致した場合の処理
break;
default:
// 上記のいずれにも一致しなかった場合の処理
}
この場合、=>
は case
の右側にある値と一致した場合に実行される処理ブロックの開始を示しています。例えば、もし value
の値が 1 の場合、case 1 =>
の下にあるコメントの箇所に処理を記述します。
同様に、もし value
の値が 2 の場合、case 2 =>
の下にあるコメントの箇所に処理を記述します。
最後の default
は、上記のケースと一致しなかった場合に実行されるブロックです。すなわち、どの case
にも一致しない場合に実行される処理を記述する箇所です。
以上を踏まえると、元のコードの =>
は case
の右側にある値と一致した場合に実行される処理ブロックの開始を示しています。それに続く行では、その case
の処理が記述されています。
例えば、case 1 =>
の場合、ThisButtonUI
を button_loud
型として作成し、他のプロパティを設定しています。
また、_ =>
は上記の例の default
と同様で、case
の右側に一致する値がない場合に実行される処理を示しています。
このように、=>
はスイッチケース文において特定の値に一致した場合の処理ブロックの開始を示すために使用されます。

フローを制御とは
クリックすると開きます。
「フローを制御」とは、プログラムの実行中に特定の条件や状態に基づいて、コードの実行の流れや進行を制御することを指します。
フローを制御することにより、異なる条件や状態に応じて適切な処理を実行したり、プログラムの実行パスを変更したりすることができます。
例えば、ガードの場合を考えてみます。ガードには複数のステートがあります(Idle、Patrol、Alert、Attack、Harvestなど)。
特定のステートに応じて、ガードが行うべき動作や振る舞いが異なります。プログラムでは、現在のガードのステートを検出し、それに基づいて対応する関数を呼び出したり、適切な処理を実行したりすることで、ガードの振る舞いや動作を制御します。
フローを制御する方法には、条件文(if文やswitch文)やループ文(for文やwhile文)を使用することが一般的です。これらの制御構造を使って、プログラムのフローを特定の条件や状態に合わせて制御し、適切な処理を実現します。
言い換えると、フローを制御することは、プログラムの実行の流れを条件や状態に依存させて調整し、目的に応じた動作や処理を行うことです。


ガードの場合、「フローを制御」とは、異なるステート(Idle、Patrol、Alert、Attack、Harvestなど)の間を切り替えながら、ガードの振る舞いや動作を制御することを指しますね!
フローを制御することは、日常生活においてもよく見られます。例えば、交差点での信号制御がフローを制御する良い例です。
交差点の信号制御では、信号機によって車の進行を制御します。特定の条件(例えば、信号が青の場合)に応じて、車は進むことができます。逆に、別の条件(例えば、信号が赤の場合)では車は停止しなければなりません。
この場合、信号機のフローを制御することで、車の進行や停止のタイミングを調整し、交差点の交通をスムーズに運行させることが目的です。
信号機のフローを制御するためには、特定の条件(信号の色)をチェックし、それに応じて車の動作を制御する必要があります。
同様に、プログラムのフローを制御する際も、特定の条件や状態を検出し、それに基づいて適切な処理や動作を行います。
フロー制御を通じて、プログラムを効率的に動作させたり、異なるシナリオに合わせて適切な処理を実行したりすることができます。

=を使用するのと同様とは
クリックすると開きます。
「=を使用するのと同様」とは、case文の機能が「=を使用するのと同様」という意味です。これは、case文が複数の可能性のある値に対してテストし、一致する値に基づいてコードを実行することができるということを指しています。
一般的なプログラミング言語では、case文やswitch文は複数のケース(case)を持ち、値の一致を評価して適切なコードブロックを実行します。この挙動は、イコール(=)演算子を使用して値の比較を行うことに類似しています。
例えば、以下のような形式のcase文を考えてみましょう。
case 値:
// コードブロック1
break;
case 別の値:
// コードブロック2
break;
default:
// デフォルトのコードブロック
この場合、case文は値と一致するケースを探し、該当するケースのコードブロックを実行します。コードブロック1やコードブロック2は、ケースの値が一致した場合に実行されます。
したがって、「=を使用するのと同様」という表現は、case文が値の比較を行い、一致した場合にコードを実行する機能を持っていることを指しています。

ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)の詳細
クリックすると開きます。
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
は、ThisButtonUI
というボタンオブジェクトがクリックされたときに HandleSelectedUIButton
という関数を呼び出すように設定しています。
具体的に説明すると、次の手順が行われます。
ThisButtonUI.OnClick()
は、ThisButtonUI
というボタンオブジェクトに「クリックされた」というイベントが発生したときを表します。.Subscribe(HandleSelectedUIButton)
は、そのイベントを受け取ったときに実行するべき関数を指定します。- ここでは、
HandleSelectedUIButton
という関数が指定されています。
- ここでは、
ボタンがクリックされると、HandleSelectedUIButton
関数が呼び出されます。
HandleSelectedUIButton
関数をボタンのクリックイベントに関連付けることで、ボタンがクリックされたときの動作を定義することができます。
例えば、HandleSelectedUIButton
関数内で他の関数を呼び出したり、他の操作を行ったりすることができます。ボタンがクリックされたときに特定のアクションを実行したい場合は、HandleSelectedUIButton
関数内に対応するコードを記述します。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)でEventを使わない理由│OnClick()を使う理由
クリックすると開きます。
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
「ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)」のコードは、ボタンがクリックされたときに特定の関数(HandleSelectedUIButton
)を呼び出すイベントの購読(サブスクライブ)を表しています。
このコードは、イベント駆動プログラミングの一例であり、UIフレームワークやプログラミング言語によって提供されるイベント処理機能を活用しています。イベントは、特定のアクションが発生したときに通知される仕組みです。ボタンのクリックは典型的なイベントの一例です。
この場合、ThisButtonUI.OnClick()
はボタンがクリックされたときのイベントを参照しています。そして、.Subscribe(HandleSelectedUIButton)
は、ボタンがクリックされたときにHandleSelectedUIButton
関数を呼び出すためにイベントに対して購読(サブスクライブ)しています。
イベント処理では、特定のアクション(ボタンのクリックなど)が発生したときに関連するコード(イベントハンドラ)を実行するために、イベントを購読する必要があります。このコードでは、ボタンがクリックされたときに特定の処理(HandleSelectedUIButton
関数)を行いたいため、OnClick()
を使用してボタンのクリックイベントを購読しています。
イベント処理には他の方法もありますが、このコードではOnClick()関数を使用することで、ボタンのクリックイベントを明示的に取り扱っています。
OnClick関数とevent関数の違い
クリックすると開きます。
OnClick関数とevent関数は、イベント処理に関連する機能ですが、少し異なる目的で使用されます。
OnClick関数は、ボタンがクリックされたときに呼び出されるイベント(サブスクリプション可能なイベント)を表しています。つまり、ボタンがクリックされたときに関数を実行するために使用されます。
OnClick関数は通常、ユーザーがボタンを操作する操作に応答して特定の処理を実行したい場合に用いられます。
一方、event関数は、パラメータ付きの反復的なイベントを表しています。このイベントは、複数のタスク間での同期を取るために使用されます。
例えば、複数のタスクがある状況で、あるタスクが特定の条件を満たしたときに他のタスクを再開させる必要がある場合に利用されます。
event関数は、タスクの実行を一時停止(中断)させ、別のタスクがイベントをシグナルし、一時停止していたタスクを順番に再開させる仕組みを提供します。
簡単に言えば、OnClick関数は単一のボタンのクリックイベントに対する処理を定義するために使われます。
一方、event関数は並行して実行されるタスク間での同期や調整に利用され、特定の条件を満たしたときにタスクを再開させたり、他のタスクとの連携を実現するために利用されます。
どちらの関数もプログラムの流れや制御のために使用されるため、理解するためにはプログラミングの基本的な概念や文脈を理解していることが重要です。
OnClick()に()をつける理由
クリックすると開きます。
.OnClick()
に()
をつけるのは、イベント購読(サブスクリプション)を行うためです。
イベント購読(サブスクリプション)を行うには、イベントオブジェクト(この場合はThisButtonUI.OnClick()
)に対して、購読(サブスクリプション)するためのメソッドを呼び出す必要があります。.OnClick()
は、その購読を行うメソッドを表しています。
一般的に、イベント購読(サブスクリプション)メソッドはカッコ(()
)を伴って呼び出されます。カッコ内には、イベントが発生したときに実行される処理や関数を指定することができます。
これにより、イベントがトリガーされた際に指定した処理が実行されるようになります。
このコードの場合、ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
は、ThisButtonUI
のOnClick
イベントに対してHandleSelectedUIButton
関数を購読(サブスクライブ)するために使用されています。
つまり、ボタンがクリックされたときにHandleSelectedUIButton
関数が呼び出されるように設定しています。
したがって、.OnClick()
に()
をつけることでイベント購読(サブスクリプション)メソッドを呼び出し、クリックされたときの処理の設定を行っているのです。

Subscribe関数の詳細
クリックすると開きます。
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
Subscribe
関数は、特定のイベントが発生した際に指定したコールバック関数を呼び出すための登録処理を行う関数です。
Subscribe
関数は、主にイベント駆動型のプログラミングにおいて使用されます。
これは、特定のアクションが発生する度に事前に指定された処理を実行したい場合に役立ちます。
例えば、ボタンをクリックしたときに「こんにちは」というメッセージを表示したいとします。
この場合、Subscribe
関数を使用して以下のようにコールバック関数を登録します。
void HandleButtonClick()
{
Console.WriteLine("こんにちは");
}
// ボタンのクリックイベントにコールバック関数を登録する
Subscribe(HandleButtonClick);
ここで、HandleButtonClick
関数がコールバック関数として定義され、Subscribe(HandleButtonClick)
によって登録されます。
この登録により、ボタンがクリックされたときにHandleButtonClick
関数が自動的に呼び出されて、コンソールに「こんにちは」というメッセージが表示されるようになります。
また、Subscribe
関数は登録解除(unsubscribing)の機能も提供しています。イベントの監視を停止したい場合は、登録時に返されるunsubscriber
オブジェクトの.Cancel()
メソッドを使用します。
var unsubscriber = Subscribe(HandleButtonClick);
// 登録を解除する
unsubscriber.Cancel();
このように、Subscribe
関数を使用すると、特定のイベントが発生した際に指定した処理を自動的に呼び出すことができます。また、必要な場合には登録解除も行うことができます。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)のまとめ
クリックすると開きます。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
コードは、ボタンがクリックされたときに特定の関数(HandleSelectedUIButton
)が呼び出されるように設定する処理です。
ThisButtonUI.OnClick()
は、ThisButtonUI
というボタンのオブジェクトがクリックされたときにイベントが発生することを表します。OnClick()
はクリック時のイベントを表す特別なオブジェクトを返します。
.Subscribe(HandleSelectedUIButton)
は、クリック時のイベントに対して特定の関数(HandleSelectedUIButton
)を登録するためのメソッドです。- つまり、
HandleSelectedUIButton
関数が実行されるようになります。
- つまり、
したがって、この部分のコードは、ThisButtonUI
というボタンがクリックされたときにHandleSelectedUIButton
関数が呼び出されるように設定しています。

HandleSelectedUIButton
関数は、ボタンがクリックされたときに実行されるべき処理を定義しています。この関数は具体的なアクションや動作を記述するために使用されます。
ボタンがクリックされたときに何らかの処理を行いたい場合、例えば他の情報を更新したり、別の関数を呼び出したり、画面の表示を変更したりする場合などに、その処理の実装をHandleSelectedUIButton
関数に記述します。
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
の部分は、ボタンのクリックイベントに対してHandleSelectedUIButton
関数を関連付けているため、ボタンがクリックされたときに自動的にHandleSelectedUIButton
関数が呼び出されるようになります。
このように関数を呼び出すことで、クリックされたイベントに応じた処理を行うことができます。
つまり、ボタンをクリックした後に実行する処理を設定するために呼び出すわけですね。

if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}の詳細
クリックすると開きます。
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
このコードは、CurrButtonUI
オブジェクトのプロパティであるButtonWidgetPerPlayer
に、エージェントをキーとして新しい値(ThisButtonUI
)をセットしています。
具体的には以下のような処理です。
CurrButtonUI.ButtonWidgetPerPlayer
は、CurrButtonUI
オブジェクトのプロパティであり、エージェント(ある種のオブジェクトやエンティティを表すもの)をキーとして別のオブジェクト(ボタンの情報やUIオブジェクトなど)を格納する辞書(連想配列)です。CurrButtonUI.ButtonWidgetPerPlayer[Agent]
は、CurrButtonUI.ButtonWidgetPerPlayer
辞書の中でキーがAgent
となる要素を取り出しています。Agent
は変数ですが、おそらくエージェントの識別子や参照を表しているものと推測されます。
=
は代入演算子であり、右辺の値(ThisButtonUI
)を左辺の変数(CurrButtonUI.ButtonWidgetPerPlayer[Agent]
)に代入します。- つまり、
CurrButtonUI.ButtonWidgetPerPlayer[Agent]
にThisButtonUI
の値をセットしています。
- つまり、
if
文は条件文を表し、条件が真(true)の場合に実行される処理を記述します。- この場合、条件式は
set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI
であり、代入の結果を評価しています。
- この場合、条件式は
- この
if
文は、CurrButtonUI.ButtonWidgetPerPlayer[Agent]
に新しい値(ThisButtonUI
)をセットするための処理です。- 実際の処理内容がないため、空の中括弧
{}
が使われています。 - このような空のブロックは、処理がないことを示すために使用されます。
- 実際の処理内容がないため、空の中括弧
つまり、このコードは、エージェントをキーとしてCurrButtonUI.ButtonWidgetPerPlayer
辞書に新しい値ThisButtonUI
をセットする処理を行っています。

CurrButtonUIの意味
クリックすると開きます。
CurrButtonUI
は、現在のボタンのUI(User Interface、ユーザーインターフェース)を表す変数またはオブジェクトの名前と思われます。この変数またはオブジェクトは、現在操作しているボタンの情報や状態を保持しています。
わかりやすく説明すると、CurrButtonUI
は、現在選択されているボタンの情報を格納するための目印のようなものです。このコードでは、ボタンのスタイルに基づいて処理を行うため、CurrButtonUI.ButtonStyle
の値が使用されています。
例えば、ButtonStyle
が1の場合には、ThisButtonUI
という新しいボタンのUIオブジェクトが作成されます。
その後、ThisButtonUI
がクリックされたときにHandleSelectedUIButton
という関数が呼び出されるように設定されます。
また、CurrButtonUI
は、ButtonWidgetPerPlayer
という辞書(連想配列)の一部でもあります。
この辞書は、エージェント(オブジェクトやエンティティ)をキーとして、対応するボタンのUIオブジェクト(ThisButtonUI
)を格納するために使われています。
つまり、CurrButtonUI
は、現在選択されているボタンのUI情報を取得または更新するための変数またはオブジェクトを表しています。

CurrButtonUIとThisButtonUIの違い
クリックすると開きます。
CurrButtonUI
とThisButtonUI
は、別々の変数もしくはオブジェクトを表しています。
CurrButtonUI
は、現在操作しているボタンのUI情報を格納するための変数もしくはオブジェクトです。この変数またはオブジェクトは、既存のボタンのUI情報を保持し、その値に基づいて処理を行うために使用されます。
一方、ThisButtonUI
は、新しいボタンのUI情報を作成するための変数またはオブジェクトです。この変数またはオブジェクトは、新しいボタンのUIの設定や初期値を保持し、後続の処理で使用されます。
例えば、デフォルトのテキストやクリック時の動作などがThisButtonUI
に設定されます。
CurrButtonUI
とThisButtonUI
の違いは、CurrButtonUI
が現在のボタンの情報を取得または更新するために使用されるのに対し、ThisButtonUI
は新しいボタンの情報を作成するために使用される点です。
このような使い分けにより、現在のボタンと新しいボタンの情報を適切に管理し、処理を分岐させることができます。

ThisButtonUIをセットする理由
クリックすると開きます。
ThisButtonUIをセットすることは、エージェントごとに異なるボタンのUI情報を格納するためです。
このコードでは、CurrButtonUIのButtonWidgetPerPlayerという辞書(連想配列)を使用して、エージェント(オブジェクトやエンティティ)ごとにボタンのUI情報を管理しています。
ButtonWidgetPerPlayer
は、エージェントをキーとして対応するボタンのUIオブジェクトを格納する辞書です。この辞書には、それぞれのエージェントに対してボタンのUI情報を個別に保持するためのエントリがあります。
ThisButtonUI
は、新しいボタンのUIオブジェクトであり、エージェントごとに異なるボタンのUI情報をセットする必要があります。そのため、CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI
のように、エージェントをキーとしてThisButtonUI
をButtonWidgetPerPlayer
にセットしています。
これにより、各エージェントが異なるボタンのUI情報を保持できます。そして、後続の処理や表示において、対応するエージェントごとのボタンのUI情報を参照することができます。
要するに、ThisButtonUIをセットすることは、エージェントごとに異なるボタンのUI情報を取り扱えるようにするための作業ということですね。

ThisButtonUIをセットしない場合、エージェントごとに異なるボタンのUI情報が正しく保持されないため、以下のような問題が生じる可能性があります:
- エージェントごとのボタンのUI情報の混乱:
- ThisButtonUIをセットしない場合、すべてのエージェントが同じボタンのUI情報を参照することになります。
- 異なるエージェントが同じUI情報を共有してしまうため、意図しない動作や表示の不整合が生じる可能性があります。
- エージェントの異なる操作に対応できない:
- 各エージェントが異なるUI操作を行うことを想定している場合、異なるボタンのUI情報を持つ必要があります。
- ThisButtonUIをセットしないと、すべてのエージェントが同じUI情報を共有するため、特定のエージェントに合わせた操作や表示のカスタマイズができなくなります。
- ボタンのクリックや表示の追跡が困難になる:
- ThisButtonUIをセットしておくことで、各ボタンがクリックされたときに適切な処理を行うための情報を持てるようになります。
- また、特定のエージェントに関連するUI情報を取得するための手段としても利用されます。
- ThisButtonUIをセットしないと、ボタンのクリックや表示の追跡が困難になり、プログラムの動作が予期しない結果になる可能性があります。
要するに、ThisButtonUIをセットすることは、正確にエージェントごとのボタンのUI情報を保持し、操作や表示の個別化を実現するために重要な手順です。
セットしない場合、ボタンのUIの一貫性や動作の正確性に関する問題が生じる可能性があるため、意図した機能や体験を提供することが難しくなります。

【重要】ButtonWidgetPerPlayerの詳細
クリックすると開きます。
ButtonWidgetPerPlayer
マップは、スタイルごとに別々のボタン情報を各エージェントごとに格納するためのマップです。
ButtonWidgetPerPlayer
マップの目的は、異なるエージェントが異なるボタンの情報を持つことができるようにすることです。
つまり、各エージェントに対して固有のボタンを提供するために使用されます。
以下のコード行を見てみましょう:
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
この行の目的は、ButtonWidgetPerPlayer
マップにエージェントをキーとして、ThisButtonUI
をセットすることです。このセット操作により、エージェントごとに異なるボタンの情報を保持することができます。
例えば、エージェントAにはButtonStyle1
のボタンが表示され、エージェントBにはButtonStyle2
のボタンが表示される場合、ButtonWidgetPerPlayer
マップは次のようになります:
ButtonWidgetPerPlayer = {
AgentA: button_loud{...} # ButtonStyle1用のボタン情報が格納されている
AgentB: button_quiet{...} # ButtonStyle2用のボタン情報が格納されている
}
こうすることで、異なるエージェントが異なるスタイルのボタンを保持し、それぞれのボタンに対して独自の表示や動作を持つことができます。また、後続の処理で特定のエージェントに関連するボタンの情報を取得する場合にも、ButtonWidgetPerPlayer
マップを参照することができます。
要するに、ButtonWidgetPerPlayer
マップはエージェントとボタン情報を関連付けるためのデータ構造であり、スタイルごとに異なるボタンを各エージェントに提供することができる仕組みを提供します。
ButtonWidgetPerPlayer
マップを使用しない場合、異なるエージェントは同じボタンの情報しか持つことができません。
通常、エージェントはそれぞれ独自の状態や設定を持ちます。そのため、異なるエージェントが異なるボタンの情報を持つことができる必要があります。
ButtonWidgetPerPlayer
マップは、エージェントごとに異なるボタンの情報を保持するための仕組みを提供します。これにより、異なるエージェントが異なるボタンスタイルやクリック時の動作を持つことができます。
例えば、エージェントAとエージェントBが存在する場合、エージェントAが「ボタンスタイル1」を表示し、エージェントBが「ボタンスタイル2」を表示するようにしたいとします。
もし ButtonWidgetPerPlayer
マップを使用しない場合、どちらか一方のエージェントのボタンスタイルしか保持できず、両方のエージェントに同じボタンスタイルが適用されます。
ButtonWidgetPerPlayer
マップは、異なるエージェントが異なるボタン情報を持つために必要なデータ構造です。
それぞれのエージェントが独自の設定や表示を持つことができるため、より柔軟なプログラミングやユーザーエクスペリエンスの提供が可能となります。

# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ThisButtonUIをbutton_loud型として作成し、デフォルトテキストにCurrButtonUIのButtonTextを設定する
ThisButtonUI := button_loud{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
# ThisButtonUIがクリックされたときにHandleSelectedUIButton関数を呼び出すように設定する
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
# CurrButtonUIのButtonWidgetPerPlayerにエージェントをキーとしてThisButtonUIをセットする
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
CurrButtonUI.ButtonWidgetPerPlayer
マップにエージェントをキーとしてボタン情報(ThisButtonUI
)をセットしています。
これにより、異なるエージェントがそれぞれ異なるボタンの情報を持つことができます。ButtonWidgetPerPlayer
マップを使用することで、各エージェントが独自の設定や表示を持つボタンを持つことができ、プレイヤーごとに異なるユーザーエクスペリエンスを提供できます。
具体的には、ThisButtonUI
を作成し、ボタンのテキストやクリック時の動作を設定した後、CurrButtonUI.ButtonWidgetPerPlayer[Agent]
のエントリにボタン情報をセットしています。
これにより、特定のエージェントに対してそのエージェント専用のボタンが提供されます。
要するに、if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
のコードは、異なるエージェントがそれぞれ独自のボタンを持つための仕組みを実現するためのものです。

CurrButtonUI.ButtonWidgetPerPlayer[Agent]
に ThisButtonUI
をセットすることで、CurrButtonUI.ButtonWidgetPerPlayer[Agent]
で取得される値は button_loud
型のウィジェット(ThisButtonUI
)になります。
具体的には、以下のコード行において ThisButtonUI
を CurrButtonUI.ButtonWidgetPerPlayer[Agent]
にセットしています。
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
これにより、CurrButtonUI.ButtonWidgetPerPlayer[Agent]
から取得される値は、エージェントごとにそれぞれ異なる button_loud
型のウィジェットになります。
セット操作によって CurrButtonUI.ButtonWidgetPerPlayer[Agent]
に関連付けられた値が更新され、以後の参照や使用時には ThisButtonUI
の内容が取得されることになります。
つまり、CurrButtonUI.ButtonWidgetPerPlayer[Agent]
で取得される値は、エージェントごとに異なる button_loud
型のウィジェットになります。
すなわち、各エージェントが保持するボタンは button_loud
ウィジェットとして取得できるということです。

2~3 =>の解説は1と同じであるため省略します。
クリックすると開きます。
2 =>
ThisButtonUI := button_quiet{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
3 =>
ThisButtonUI := button_regular{DefaultText := StringToMessage(CurrButtonUI.ButtonText)}
ThisButtonUI.OnClick().Subscribe(HandleSelectedUIButton)
if(set CurrButtonUI.ButtonWidgetPerPlayer[Agent] = ThisButtonUI){}
ButtonStyleが1, 2, 3以外の場合の詳細
クリックすると開きます。
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
CurrButtonUI
の ButtonStyle
の値によって処理を分岐するコードスニペットです。
詳細は以下のとおり。
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
_ =>
は「それ以外の場合」という意味です。つまり、ButtonStyle
が 1, 2, 3 以外の場合にこの分岐に入ります。Print("~ERROR: ButtonStyle integer over/under-flow")
はエラーメッセージを出力するためのコードです。Print
は一般的には結果やメッセージを表示するために使用される関数です。- ここでは、
"~ERROR: ButtonStyle integer over/under-flow"
というメッセージを表示しています。 - 「ButtonStyle の整数が範囲外です」といったエラーメッセージを出力することを意図しているようです。
~ERROR
は特定の形式や規則ではなく、単に識別子として使用されている文字列です。
このコードスニペットでは、ButtonStyle
の値が 1, 2, 3 以外の場合にエラーメッセージを表示します。これはその他の未定義や無効な ButtonStyle
の値への対応を行うためのセクションです。エラーメッセージの内容は実際の要件や目的に応じて変更される可能性があります。
CanvasArray := ReturnCanvasSlots(Agent):の詳細│ReturnCanvasSlotsの定義(含)
クリックすると開きます。
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
関数 ReturnCanvasSlots(Agent : agent):[]canvas_slot
が CanvasArray
という変数にキャンバススロットの配列を代入しています。
以下では、業務ロジックに基づいた解説を行います。
ReturnCanvasSlots(Agent : agent):[]canvas_slot =
var CanvasSlotArray : []canvas_slot = array{}
for(ThisButtonUI : ButtonUI):
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
Agent.LoadButtonState(ThisButtonUI)
ThisSlot := canvas_slot:
Offsets := margin{Top := ThisButtonUI.ButtonPosition.Y, Left := ThisButtonUI.ButtonPosition.X, Bottom := ThisButtonUI.ButtonSize.Y, Right := ThisButtonUI.ButtonSize.X}
ZOrder := 0
SizeToContent := ThisButtonUI.SizeToContent
Widget := ThisWidget
set CanvasSlotArray += array{ThisSlot}
return CanvasSlotArray
まず、CanvasSlotArray
という名前の空の canvas_slot
の配列を作成します。
次に、ButtonUI
の各要素に対してループ処理を行います。ThisButtonUI
は現在のループイテレーションで処理する ButtonUI
の要素です。
ThisButtonUI.ButtonWidgetPerPlayer[Agent]
は、特定のエージェント (Agent
) のために指定された ButtonUI
のウィジェット (ButtonWidget
) を表します。
条件式 if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent])
は、ButtonWidget
が存在する場合に真となり、その時のウィジェットが ThisWidget
に代入されます。
Agent.LoadButtonState(ThisButtonUI)
の部分は、エージェント (Agent
) のために ThisButtonUI
のボタン状態をロードする関数呼び出しです。具体的な実装は提供されていませんが、おそらく ButtonUI
の設定に基づいてボタンの状態(有効/無効、可視性など)を設定する役割を持つ関数であると推測されます。
次に、ThisSlot
という名前の canvas_slot
を作成します。canvas_slot
は、キャンバス上のウィジェットの配置やプロパティを指定するためのオブジェクトです。ThisSlot
には以下のプロパティが設定されます:
Offsets
:- ボタンの位置とサイズを指定する
margin
オブジェクトです。 ThisButtonUI.ButtonPosition.Y
、ThisButtonUI.ButtonPosition.X
、ThisButtonUI.ButtonSize.Y
、ThisButtonUI.ButtonSize.X
を使って設定されます。
- ボタンの位置とサイズを指定する
ZOrder
:- ウィジェットの表示順序を指定する整数値です。
- ここでは常に 0 となっています。
SizeToContent
:- ウィジェットのサイズをコンテンツに応じて自動調整するかどうかを示すブール値です。
ThisButtonUI.SizeToContent
を使用します。
Widget
:- ウィジェット (
ThisWidget
) を指定します。
- ウィジェット (
CanvasSlotArray
に ThisSlot
を追加するため、CanvasSlotArray += array{ThisSlot}
という式が使用されます。これにより、ループの各イテレーションで作成した ThisSlot
が CanvasSlotArray
に追加されます。
最後に、関数から CanvasSlotArray
を返します。
つまり、ReturnCanvasSlots
関数は特定のエージェント (Agent
) のために、ButtonUI
から取得したウィジェットとウィジェットのプロパティを使用してキャンバススロットを作成し、それらのスロットを含む配列を返します。
この配列は CanvasArray
という変数に格納されます。
CanvasArray := ReturnCanvasSlots(Agent)の記述理由
クリックすると開きます。
CanvasArray := ReturnCanvasSlots(Agent)
は、関数ReturnCanvasSlots
を呼び出してエージェントに対応するキャンバススロットの配列を取得し、その結果をCanvasArray
という変数に代入するための記述です。
このコードでは、ReturnCanvasSlots(Agent)
は別の関数であり、エージェントに対応するキャンバススロットの配列を返します。その返り値であるキャンバススロットの配列を変数CanvasArray
に代入するために、:=
演算子を使っています。
CanvasArray
は、関数CreateMyUI
のローカル変数であり、関数の最後でMyInteractableButtons
という変数に割り当てられます。MyInteractableButtons
はcanvas
型のオブジェクトで、そのSlots
プロパティにCanvasArray
が設定されます。
このように、CanvasArray := ReturnCanvasSlots(Agent)
の記述は、CreateMyUI
関数内で別の関数を呼び出し、その結果を利用して変数に代入するためのステップです。
ReturnCanvasSlots
関数がエージェントに対応するキャンバススロットの配列を返すことで、その値をCanvasArray
に保持することができますね。
これにより、CanvasArray
の値は後続の処理で使用されることになります。

【イメージ】
例えば、小学生のみんなでゲームを作るためのプログラムを考えましょう。
その中で、ボタンを表示するためのUIを作成する関数CreateMyUI
があります。
CreateMyUI(Agent : agent) : canvas =
# ボタンUIの各要素に対してループを実行する
for(CurrButtonUI : ButtonUI):
# CurrButtonUIのButtonStyleの値によって処理を分岐する
case(CurrButtonUI.ButtonStyle):
# ButtonStyleが1の場合
1 =>
# ...
# (ボタンの処理)
# ...
# ButtonStyleが2の場合
2 =>
# ...
# (ボタンの処理)
# ...
# ButtonStyleが3の場合
3 =>
# ...
# (ボタンの処理)
# ...
# ButtonStyleが1, 2, 3以外の場合
_ =>
# エラーメッセージを出力する
Print("~ERROR: ButtonStyle integer over/under-flow")
CanvasArray := ReturnCanvasSlots(Agent)
# ...
# (その他の処理)
# ...
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
return MyInteractableButtons
CanvasArray := ReturnCanvasSlots(Agent)
は、関数内でReturnCanvasSlots(Agent)
という関数を呼び出し、その結果をCanvasArray
という変数に代入するための行です。
例えば、このプログラムを使って、Agent
がプレイヤー1の場合を考えてみましょう。この関数は、Agent
に対応するボタンのUIを作成し、それを表示するためのキャンバスを設定します。
ReturnCanvasSlots(Agent)
は、Agent
に対応するキャンバススロットの配列を返します。
例えば、プレイヤー1の場合、戻り値として[1, 2, 3]
が返るとします。
それをCanvasArray
に代入することで、CanvasArray
の値は[1, 2, 3]
となります。
その後、MyInteractableButtons
という変数にcanvas
型のオブジェクトを作成し、そのSlots
プロパティにCanvasArray
を設定します。
このようにすることで、関数の最後で変数MyInteractableButtons
は以下のような形になります。
MyInteractableButtons : canvas = canvas:
Slots := [1, 2, 3]
そして、最終的にMyInteractableButtons
が関数から返されます。
この例では、ReturnCanvasSlots
関数が具体的に何を行うかは示されていませんが、仮想的にはエージェントに依存した適切なキャンバススロットの配列を返す関数であると考えてください。
キャンバススロットの配列とは
クリックすると開きます。
キャンバススロットの配列は、情報やオブジェクトを格納するための「スロット」と呼ばれるコンテナを複数持つ連続的なデータの集まりです。各スロットは、データやオブジェクトを格納するための場所として機能します。
イメージするために、棚に本を収納することを考えてみましょう。棚は複数の水平なスロットで構成されていて、各スロットには本を一冊ずつ収納することができます。
スロットは順番に並んでおり、それぞれのスロットには任意の本が格納されています。
同様に、キャンバススロットの配列も複数のスロットから構成されています。各スロットには特定のデータやオブジェクトが格納されていて、それらを必要に応じて取り出したり変更したりすることができます。
例えば、ゲームのユーザーインターフェース(UI)を考える場合、キャンバススロットの配列はボタンやテキストなどのUI要素を格納するために使用されるかもしれません。
具体的な例として、3つのキャンバススロットを持つ配列を考えてみましょう。第1のスロットには「ボタンA」が、第2のスロットには「テキストボックス」が、第3のスロットには「画像」が格納されているとします。
この場合、キャンバススロットの配列は次のように表現されます。
[スロット1: ボタンA, スロット2: テキストボックス, スロット3: 画像]
この配列には異なる種類のオブジェクトが格納されていることが分かります。各スロットには特定のオブジェクトまたはデータが関連付けられており、プログラムの他の部分から必要な情報を取得するために使用されます。
キャンバススロットの配列は、データやオブジェクトを保持するための効果的な手段であり、それらを構造化して管理することができます。
これにより、プログラムやゲームの画面上で必要な要素を適切に配置するなど、柔軟な操作や表示が可能になります。

キャンバススロットの配列を取得する必要がある理由は、エージェントに関連するキャンバススロットの情報を得るためです。
キャンバススロットは、エージェントが持つ情報や機能を表現するためのコンテナであり、それらの配列を取得することで、エージェントの現在の状態を知ることができます。
関数ReturnCanvasSlotsは、エージェントに対応するキャンバススロットの配列を返すためのものです。これにより、他の部分のプログラムがエージェントの状態や機能にアクセスできるようになります。
返されたキャンバススロットの配列は、他の要素と組み合わせたり、特定の操作を実行したりすることができます。
具体的な例として、ゲームの場合を考えてみましょう。エージェントはプレイヤーキャラクターであり、キャンバススロットはプレイヤーの能力やアイテムなどを表現します。
ReturnCanvasSlotsを呼び出してキャンバススロットの配列を取得することにより、他の部分のプログラムはプレイヤーキャラクターの能力やアイテムの情報を取得し、それに基づいてゲームの進行や表示を制御することができます。
要するに、キャンバススロットの配列を取得することで、エージェントの情報や機能にアクセスし、それを他の処理に活用することができるのです。
これにより、プログラムやシステムの柔軟性や拡張性が向上し、より効果的な開発や操作が可能になります。

MyInteractableButtons : canvas = canvas:の詳細
クリックすると開きます。
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
MyInteractableButtons: canvas = canvas:
は、変数MyInteractableButtons
を作成し、それをcanvas
型として定義しています。
プログラミングでは、変数はデータを格納するための箱のようなものです。この場合、MyInteractableButtons
はキャンバスUIを表現するための変数で、canvas
型という特定のデータ型を持ちます。
canvas:
は、canvas
型のインスタンスを生成するための記述です。インスタンスとは、特定のデータ型(クラスと呼ばれるもの)の実体化したもののことです。つまり、canvas
型のデータを実際に作り出している部分です。
その後の=
記号は、変数MyInteractableButtons
に生成したcanvas
型のインスタンスを代入していることを示しています。変数に値を代入することで、その変数は生成したインスタンスを参照することができます。
つまり、MyInteractableButtons
は、生成したキャンバスUIのデータを格納するための変数となります。この変数を通じて、キャンバスUIに関する情報を取得したり、別の場所で利用したりすることができます。
MyInteractableButtons : canvas = canvas:の最後に「:」をつける理由
クリックすると開きます。
canvas:
の:
は、ブロックを表すための構文です。この:
は、そのブロックの開始を示します。
このコードでは、MyInteractableButtons
という変数を定義し、それをcanvas
型の変数として宣言しています。
その後、canvas
型の変数であるMyInteractableButtons
の内部に、Slots := CanvasArray
という行でSlots
属性にCanvasArray
を設定しています。
このように、ブロック内での処理を示すために、MyInteractableButtons : canvas = canvas:
という表記が行われています。
canvasクラスの詳細
クリックすると開きます。
canvasクラスは、Unreal EngineにおけるUI要素を配置するためのコンテナウィジェットです。このクラスを使用することで、任意の位置にウィジェットを配置することができます。
canvasクラスは、widgetクラスを継承しており、UIの要素を表示するための基本クラスです。canvasクラスには、データメンバと関数が含まれています。
データメンバ:
- Slots([]canvas_slot型):
- キャンバスの子ウィジェット。
- ウィジェットの初期化時にのみ使用され、AddWidgetやRemoveWidgetによって変更されません。
関数:
- AddWidget:
- 新しい子スロットをキャンバスに追加します。
- GetParentWidget:
- ウィジェットの親ウィジェットを取得します。
- 親が存在しない場合(例:このウィジェットがplayer_uiに含まれていない場合やルートウィジェット自体である場合)は失敗します。
- GetRootWidget:
- このウィジェットをplayer_uiに追加したウィジェットを取得します。
- ルートウィジェット自体である場合は自身を返します。
- このウィジェットがplayer_uiに含まれていない場合は失敗します。
- GetVisibility:
- 現在のウィジェットの表示状態を取得します。
- IsEnabled:
- ウィジェットがプレイヤーによってインタラクティブに変更可能かどうかを取得します。
- RemoveWidget:
- 指定したウィジェットを含むスロットを削除します。
- SetEnabled:
- プレイヤーがこのウィジェットとのインタラクションを有効化または無効化します。
- SetVisibility:
- ウィジェットを表示または非表示にしますが、player_uiから自体を削除しません。
- 詳細については、widget_visibilityを参照してください。
canvasクラスは、UI要素を組み合わせて複雑なインタラクティブなUIを作成する際に使用されます。このクラスは、Unreal EngineのUIシステムにおける重要な要素の一つであり、プレイヤーの画面上にウィジェットを配置する柔軟性を提供します。
Slots := CanvasArrayの詳細
クリックすると開きます。
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
Slots := CanvasArray
は、Slots
という変数にCanvasArray
という値を設定する代入文です。
Slots
はCanvasArray
という変数に対応するリスト(配列)であり、CanvasArray
はReturnCanvasSlots(Agent)
という関数から返されるエージェントに対応するキャンバススロットの配列です。
この代入文は、変数Slots
にCanvasArray
のコピーを設定することを意味します。
つまり、Slots
とCanvasArray
は同じ情報を参照することになります。
これにより、MyInteractableButtons
という変数がcanvas
型として作成され、そのSlots
にはCanvasArray
の内容が含まれます。
MyInteractableButtons
は、その後の処理で利用されるキャンバスオブジェクトとして使用されることが想定されています。
簡単に言うと、Slots := CanvasArray
は、CanvasArray
の値をコピーしてSlots
に設定することで、MyInteractableButtons
オブジェクトのSlots
属性に対応するキャンバススロットの配列を設定しているということです。

return MyInteractableButtonsの詳細
クリックすると開きます。
# エージェントに対応するキャンバススロットの配列を取得する
CanvasArray := ReturnCanvasSlots(Agent)
# MyInteractableButtonsをcanvas型として作成し、SlotsにCanvasArrayを設定する
MyInteractableButtons : canvas = canvas:
Slots := CanvasArray
# MyInteractableButtonsを返す
return MyInteractableButtons
return MyInteractableButtons
は、関数CreateMyUI
が実行された結果として、MyInteractableButtons
という変数を返すことを意味します。
MyInteractableButtons
はcanvas
型のオブジェクトであり、それが関数の結果として返されます。関数の呼び出し元で、この戻り値が別の変数に代入されるか、直接使用されることが想定されています。
具体的には、関数CreateMyUI
はボタンのUIを作成し、それらを含んだキャンバスオブジェクトMyInteractableButtons
を生成します。その後、この生成されたキャンバスオブジェクトが関数の戻り値として返されます。
戻り値の使用方法は、関数を呼び出したコードの文脈によって異なります。例えば、次のように関数を呼び出し、戻り値を変数に代入することができます。
result := CreateMyUI(agent)
この場合、result
という変数にMyInteractableButtons
が代入されます。これにより、後続のコードでresult
を使用することができます。また、関数呼び出し時に直接結果を利用することもできます。
SomeOtherFunction(CreateMyUI(agent))
この場合、関数SomeOtherFunction
にはCreateMyUI
の戻り値として得られたMyInteractableButtons
が直接渡されます。
要するに、return MyInteractableButtons
は関数の結果として生成されたMyInteractableButtons
を返す文であり、関数を呼び出したコードでその値を活用することができるということです。

ReturnCanvasSlots(Agent : agent):[]canvas_slot=~の詳細
ReturnCanvasSlots(Agent : agent):[]canvas_slot=
var CanvasSlotArray : []canvas_slot = array{}
for(ThisButtonUI : ButtonUI):
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
Agent.LoadButtonState(ThisButtonUI)
ThisSlot := canvas_slot:
Offsets := margin{Top := ThisButtonUI.ButtonPosition.Y, Left := ThisButtonUI.ButtonPosition.X, Bottom := ThisButtonUI.ButtonSize.Y, Right := ThisButtonUI.ButtonSize.X}
ZOrder := 0
SizeToContent := ThisButtonUI.SizeToContent
Widget := ThisWidget
set CanvasSlotArray += array{ThisSlot}
return CanvasSlotArray
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for ThisButtonUI in ButtonUI:
# 特定のエージェントに関連するウィジェットが存在する場合
if ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]:
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
このコードの目的は、指定されたエージェントに関連するボタンウィジェットを使用して、キャンバススロットを作成し、それらを含む canvas_slot
の配列を返すことです。
各スロットは、ウィジェットの位置、サイズ、表示順序、サイズの自動調整などの属性を持ちます。
ループを通じて、対象のエージェントに関連するボタンウィジェットの情報を取得し、それを元にキャンバススロットを作成しています。最終的に、作成されたスロットが CanvasSlotArray
に格納され、その配列が関数の戻り値として返されます。
詳細は以下のとおり。
ReturnCanvasSlots(Agent : agent):[]canvas_slot=
この行は、関数 ReturnCanvasSlots
を定義し、引数として Agent
を受け取り canvas_slot
の配列を返すことを示しています。
var CanvasSlotArray : []canvas_slot = array{}
この行は、CanvasSlotArray
という名前の空の canvas_slot
配列を作成しています。
for(ThisButtonUI : ButtonUI):
この行は、ButtonUI
の各要素に対して順次処理を行うループを開始しています。
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
この行は、特定のエージェントに関連するウィジェットが存在するかチェックしています。
もし存在する場合、ThisWidget
にそのウィジェットを代入します。
Agent.LoadButtonState(ThisButtonUI)
この行では、Agent
のボタンの状態を ThisButtonUI
に読み込んでいます。
ThisSlot := canvas_slot:
Offsets := margin{Top := ThisButtonUI.ButtonPosition.Y, Left := ThisButtonUI.ButtonPosition.X, Bottom := ThisButtonUI.ButtonSize.Y, Right := ThisButtonUI.ButtonSize.X}
ZOrder := 0
SizeToContent := ThisButtonUI.SizeToContent
Widget := ThisWidget
このブロックは、canvas_slot
オブジェクト ThisSlot
を作成しています。
それぞれの属性には以下の値が設定されています:
Offsets
:margin
オブジェクトであり、ThisButtonUI
のボタンの位置とサイズを示しています。
ZOrder
:- 表示順序を表す整数であり、ここでは初期値の
0
が設定されています。
- 表示順序を表す整数であり、ここでは初期値の
SizeToContent
:- コンテンツに応じて自動サイズ調整をするかどうかを示すブール値で、
ThisButtonUI
のSizeToContent
の値が設定されています。
- コンテンツに応じて自動サイズ調整をするかどうかを示すブール値で、
Widget
:ThisWidget
というウィジェットオブジェクトへの参照です。
set CanvasSlotArray += array{ThisSlot}
この行では、作成した ThisSlot
を CanvasSlotArray
に配列として追加しています。
return CanvasSlotArray
最後の行では、CanvasSlotArray
を関数の戻り値として返しています。
このコードの最大の目的は、特定のエージェントに関連するボタンの情報から、ボタンを配置するための canvas_slot
オブジェクトの配列を作成し、それを返すことです。
コードの流れと目的は以下のとおり。
- ボタンの配置情報を格納するための空の配列
CanvasSlotArray
を作成します。 ButtonUI
の各要素に対して順番に処理を行います。ButtonUI
は、ボタンの情報を含むリストです。
- 各ボタンについて、特定のエージェントに関連するウィジェット(ボタンに対応するGUI要素)が存在するかをチェックします。
- ウィジェットが存在する場合、そのウィジェットに関連するボタンの状態を特定のエージェントに読み込みます。
- 新しい
canvas_slot
オブジェクト(ボタンを配置するためのスロット情報)を作成します。 canvas_slot
オブジェクトには、ボタンの位置やサイズを示すOffsets
、表示順序を示すZOrder
、コンテンツに応じた自動サイズ調整を示すSizeToContent
、そしてウィジェットへの参照Widget
が含まれます。- 作成した
canvas_slot
オブジェクトをCanvasSlotArray
配列に追加します。 - 全てのボタンについて処理が終わったら、最終的な
CanvasSlotArray
を関数の戻り値として返します。
つまり、このコードは特定のエージェントに対してボタンを配置するための canvas_slot
オブジェクトのリストを作成し、それを返します。このリストはボタンの位置や状態などを管理するのに役立ちます。

このコードの目的は、指定されたエージェントに関連するボタンウィジェットを使って、複数のキャンバススロットを作成し、それらを含む canvas_slot の配列を返すことです。
例えば、想像してみてください。
あなたが部屋のレイアウトを設計しているとします。部屋には複数の家具がありますが、それぞれの家具には特定の場所に配置する必要があります。
この場合、ボタンウィジェットは家具を表し、キャンバススロットは家具が配置される場所を表します。
あなたは特定のエージェント(例えば、ユーザー)に対して動的なGUIを作成したいと考えています。
そのGUIには、エージェントに関連するボタンウィジェット(家具)が含まれます。
このコードは、エージェントに関連するボタンウィジェット(家具)を使用して、各家具を適切な場所に配置するためのキャンバススロットを作成します。
そして、それらのキャンバススロットを含む配列を返します。この配列は、後でGUIをビルドする際に使用されます。
要するに、このコードは、エージェントに関連するボタンウィジェットを使って、家具を配置するための情報を作成し、それを管理するための配列を返すものです。

canvas_slot 構造体の詳細
クリックすると開きます。
canvas_slot
構造体について詳しく説明しましょう。
以下にメンバー情報を含んだものを提供します。
メンバー
この構造体にはデータメンバーがありますが、関数はありません。
データ
以下に、canvas_slot
構造体の各データメンバーの詳細を説明します。
- Anchors(アンカー):
- このメンバーは、マージンやウィジェットが親要素との相対的なサイズ変更をどのように扱うかを定義します。
- 値は0.0から1.0の間で定義されます。
- Offsets(オフセット):
- このメンバーは、ウィジェットのサイズと位置を定義するオフセットです。
- アンカーが適切に定義されている場合、Offsets.Left は Anchors.Minimum.X からの距離(ピクセル単位)を表し、Offsets.Bottom は Anchors.Maximum.Y からの距離(ピクセル単位)を表します。
- これにより、ウィジェットのサイズを制御します。
- アンカーが適切に定義されていない場合、Offsets.Left と Offsets.Top はウィジェットの位置を、Offsets.Right と Offsets.Bottom はウィジェットのサイズを表します。
- SizeToContent(サイズの自動調整):
- このメンバーが true の場合、ウィジェットの希望するサイズが使用されます。
- Offsets によって計算されるサイズは無視されます。
- Alignment(配置):
- このメンバーは、ウィジェットのピボット/原点の位置を表します。左上を (0.0, 0.0) とし、右下を (1.0, 1.0) とします。
- ZOrder(Zオーダー):
- このスロットの Z オーダーは、このキャンバスパネル内の他のスロットに対しての相対的な表示順序を示します。
- 値が高いほど最後に描画され、上に表示されるように見えます。
- Widget(ウィジェット):
- このスロットに割り当てられたウィジェットです。
これらのデータメンバーを使って、canvas_slot
構造体はウィジェットのサイズ、位置、サイズの自動調整、ピボットの配置など、ウィジェットの配置や表示に関する情報を保持します。
また、Zオーダーによってウィジェットの表示順序を制御することもできます。
この構造体を使用して、ウィジェットを適切に配置してキャンバスパネル上に表示することができます。

ReturnCanvasSlots(Agent: agent): []canvas_slot =の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for ThisButtonUI in ButtonUI:
# 特定のエージェントに関連するウィジェットが存在する場合
if ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]:
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
このコードは、指定されたエージェントに関連するボタンウィジェットを使って、キャンバススロットを作成し、それらを含む canvas_slot
の配列を返す関数です。
まず、空の canvas_slot
配列 CanvasSlotArray
を作成します。
次に、ButtonUI
内の各要素(ボタンの情報を表すオブジェクト)に対してループ処理を行います。
if
文を使用して、特定のエージェントに関連するウィジェット(ボタン)が存在するかをチェックします。もし存在する場合は、以下の処理を行います。
- エージェントに対して、そのボタンの状態を読み込みます。
- 新しい
canvas_slot
オブジェクトThisSlot
を作成します。 ThisSlot
内のデータメンバーに以下の情報を設定します:Offsets
: ボタンの位置とサイズを示すマージン情報を指定します。ZOrder
: ウィジェットの表示順序を設定します。SizeToContent
: ウィジェットのサイズをコンテンツに応じて自動的に調整するかどうかを設定します。Widget
: ボタンウィジェットへの参照を設定します。CanvasSlotArray
に作成したThisSlot
を追加します。
最後に、CanvasSlotArray
を関数の戻り値として返します。
つまり、この関数は、指定されたエージェントに関連するボタンウィジェットを使って、ボタンの位置、サイズ、表示順序などの情報を canvas_slot
オブジェクトとして作成し、それらを配列に追加して返すものです。これにより、後でグラフィカルユーザーインターフェース(GUI)を構築する際に使用できます。
ReturnCanvasSlots(Agent: agent): []canvas_slot = で[]をつける理由
クリックすると開きます。
結論からいうと、配列[]を使うためです。
配列が必要な理由は、複数の canvas_slot
オブジェクトをまとめて管理したり、複数の要素を持つデータ構造を扱うためです。
ReturnCanvasSlots
関数では、複数の canvas_slot
オブジェクトを作成し、それらを配列にまとめて返しています。これにより、呼び出し元で配列の要素を順番に処理したり、一括で繰り返し処理を行ったりすることができます。
配列を使うことで、関連するデータを一つのまとまりとして扱うことができます。また、データの追加や削除も柔軟に行えます。例えば、後で他の要素を追加したい場合には、既存の配列に要素を追加するだけで済みます
配列は一般的に、同じ型の要素を複数持つ場合や、可変長のデータ集合を扱う場合に便利です。ReturnCanvasSlots
関数では、複数の canvas_slot
オブジェクトを扱う必要があるため、配列が必要となっています。

var CanvasSlotArray: []canvas_slot = array{}を記述する理由
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
上記のコードは、関数 ReturnCanvasSlots
内で空の canvas_slot
配列を作成するために記述されています。
この記述が必要な理由は、次のようなものです:
- 配列の初期化:
- コードの第3行で
CanvasSlotArray
という変数を宣言し、それに空の配列array{}
を代入しています。 - この初期化の目的は、関数の呼び出し時に初期値が必要な場合や、関数内で使用される変数が必ずしも引数から得られない場合に備えるためです。
- ここでは、関数が呼び出された際に空の
canvas_slot
型の配列を返すことが期待されているため、最初に空の配列を用意しているのです。
- コードの第3行で
- 変数のスコープ:
CanvasSlotArray
変数のスコープは関数ReturnCanvasSlots
内に制限されています。- そのため、関数外からこの変数に直接アクセスすることはできません。
- このような局所的なスコープを持つ変数は、関数内で一時的な計算やデータ保持に用いられることがあります。
- この場合、関数が呼び出された時に都度新たな空の配列を作成する必要が生じるため、関数内で変数を宣言して初期化する必要があります。
以上の理由から、このコードでは ReturnCanvasSlots
という関数を定義し、関数内で変数 CanvasSlotArray
を宣言して空の配列を用意しています。
これにより、関数が呼び出された際に常に空の配列が返されるようになっています。

関数 ReturnCanvasSlots
では、関数が呼び出された際に空の canvas_slot
配列が返るようにするために、変数 CanvasSlotArray
を宣言しています。
このコードでは、関数の定義部分で変数 CanvasSlotArray
が宣言されており、空の配列 array{}
で初期化されています。そして、関数内の処理でループを実行し、各ループごとに新しい canvas_slot
オブジェクトを作成し、それを CanvasSlotArray
に追加しています。
最終的に、CanvasSlotArray
を関数の戻り値として返すことで、関数を呼び出した際に空の配列が返されるようになります。
この配列は、関数内で作成された canvas_slot
オブジェクトの集まりとなります。
したがって、このコードでは関数を呼び出した際に空の配列が返るように変数を宣言しています。
【空の配列を返す目的】
このコードで空の配列が返される理由には複数の可能性があります。
以下にいくつかの考えられる理由を挙げます:
- ボタンが存在しない場合:
- このコードは
ButtonUI
の各要素に対してループ処理を行っていますが、もしButtonUI
が空であったり、すべての要素に関連するウィジェットが存在しなかった場合、つまりボタンが存在しない場合、CanvasSlotArray
は空のままになります。 - その結果、関数を呼び出しても空の配列が返されます。
- このコードは
- ボタンの状態の読み込みに失敗した場合:
- コード中の
Agent.LoadButtonState(ThisButtonUI)
の部分で、ボタンの状態を読み込む処理が行われます。 - もし読み込みに失敗した場合、
CanvasSlotArray
には新しいcanvas_slot
オブジェクトが作成されず、結果的に空の配列が返されます。
- コード中の
- ウィジェットへの参照が存在しない場合:
ThisButtonUI
に関連する特定のエージェント専用のウィジェットが存在しない場合、つまりThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]
の部分でウィジェットへの参照が取得できない場合、CanvasSlotArray
に新しいcanvas_slot
オブジェクトが作成されず、空の配列が返されます。
上記のような理由があるため、このコードでは関数を呼び出した際に空の配列が返されるようになっています。もし異なる動作や結果が必要な場合は、それに対応する修正を行う必要があります。
空の配列を返す目的は、関数を呼び出した結果としてデータがない状態を表すことです。
この特定の関数では、ボタンの情報を基に canvas_slot
オブジェクトの配列を作成しています。しかし、もしボタンが存在しない場合や特定のエージェントに関連するボタンがない場合など、生成するデータがない可能性もあります。
そのため、関数を呼び出した結果として空の配列を返すことで、そのような状況を表現するのです。
空の配列は要素がないため、何も生成されなかったことを示します。
これにより、関数の呼び出し元で戻り値を受け取った際に、データの有無を簡単に判定できます。
例えば、関数の戻り値を受け取った後、戻り値の配列が空であれば「データなし」という条件分岐を行うことができます。
それによって、プログラムの制御フローを適切に調整したり、ユーザーにフィードバックを提供したりすることが可能です。
配列使用時の初期化について
クリックすると開きます。
配列を使用する際には、初期化することが一般的に推奨されます。初期化は、変数が使用される前に適切に設定されることを保証するための重要なステップです。
配列を宣言しただけでは、要素にはデフォルトの初期値が割り当てられますが、それが意図した初期状態であるとは限りません。デフォルトの初期値は言語やコンテキストによって異なる場合があります。そのため、明示的に初期化して正しい初期状態を設定することが重要です。
空の配列を作成し、その後の操作で要素を追加していく場合は、初期化のステップが必要です。これにより、操作の前に配列がクリアされていることが保証されます。また、配列の要素を使用する前に予期せぬ値の影響を受ける心配も減ります。
したがって、配列を使用する際には初期化することが望ましいです。これにより、コードの可読性と信頼性が向上し、バグを防ぐことができます。
for(ThisButtonUI : ButtonUI):の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
for文は、ある範囲内の要素に対して順番に処理を行うための制御構造です。
この場合、ButtonUIという配列やリストの中の要素に対して、一つずつ処理を行います。
具体的には、ButtonUI内の要素を順番に取り出して、変数ThisButtonUIに代入しながら以下の処理を行います。
- 条件式
if ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]:
により、特定のエージェントに関連するウィジェットが存在するかチェックします。- この条件が真(True)の場合のみ、if文の中の処理が実行されます。
- 特定のエージェントに対して、ThisButtonUIのボタンの状態を読み込みます。
- 新しいcanvas_slotオブジェクトを作成します。
- このcanvas_slotオブジェクトには、ボタンの位置やサイズ、表示順序、サイズ調整の設定、ウィジェットへの参照が含まれます。
- 作成したThisSlotをCanvasSlotArrayという配列に追加します。
- 既存の要素にこの新しい要素を連結させます。
以上の処理を、ButtonUI内の全ての要素に対して繰り返します。
最終的に、CanvasSlotArrayという配列が関数の戻り値として返されます。
このように、for文を使用することで、配列やリストの要素に対して順番にアクセスし、各要素に対して同じ処理を適用することができます。

if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent])
は、変数ThisWidgetにThisButtonUI.ButtonWidgetPerPlayer[Agent]の値を代入しながら、同時に条件判定を行っています。
変数ThisWidgetにThisButtonUI.ButtonWidgetPerPlayer[Agent]の値を代入し、かつその結果が真(True)であれば、if文の中の処理を実行します。
具体的には、ThisButtonUI.ButtonWidgetPerPlayer[Agent]は特定のエージェントに関連するウィジェットの値であり、「ウィジェットが存在するかどうか」を判定するために使われます。
この行の目的は、特定のエージェントに関連するウィジェットが存在する場合にのみ、if文の中の処理を実行することです。
条件判定の結果が真の場合、ThisWidgetにウィジェットの値が代入され、その後の処理で参照されることになります。
わかりやすく説明すると、この行の意味は次のようになります:
「もし、特定のエージェントに関連するウィジェットが存在すれば、そのウィジェットの値をThisWidgetという変数に代入して、以下の処理を実行します。存在しなければこのif文の中はスキップします。」
これにより、特定のエージェントに関連するウィジェットが存在するかどうかを確認し、条件を満たす場合にのみ処理を実行することができます。


Agent.LoadButtonState(ThisButtonUI)の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
Agent.LoadButtonState(ThisButtonUI)
は、特定のエージェントに対して、指定されたボタンの状態を読み込むための操作(メソッドや関数)です。
Agent
は特定のエージェントを表すオブジェクトまたはインスタンスを指します。LoadButtonState
はAgent
オブジェクトに定義された操作であり、引数としてThisButtonUI
(ボタンの情報を保持するオブジェクト)を受け取ります。
この操作は、ボタンの状態をエージェントに読み込むために使用されます。具体的には、ボタンが押されたかどうかや有効/無効の状態など、ボタンに関する情報をエージェントに伝える役割があります。
この行の目的は、エージェントに対して特定のボタンの状態を読み込ませることです。
この処理により、ボタンの状態情報がエージェントに反映され、適切な動作や表示を行うことができます。
わかりやすく説明すると、この行の意味は次のようになります:
「特定のエージェントに対して、このボタンの状態を読み込んでください。」
エージェントに特定のボタンの状態を設定することで、その後の処理や表示に反映されるようになります。

【イメージ】
この操作は、ボタンの情報をエージェントに伝える役割を果たします。
例えば、ゲームのUIに「攻撃する」というボタンがあるとします。このボタンが押されたとき、エージェントは攻撃を行う必要があります。しかし、エージェントが直接ボタンの状態を認識することはできません。
そこで、プログラムではボタンの状態をエージェントに伝える必要があります。Agent.LoadButtonState(ThisButtonUI)
という操作は、そのために使用されます。
この操作は、特定のエージェントに対して特定のボタン(ThisButtonUI
)の状態を読み込むことを意味します。
例えば、ボタンが押されているかどうか、有効な状態かどうかなどの情報をエージェントに伝えます。
エージェントはこの情報を受け取り、ゲームのルールに従って適切な動作を行うことができます。もしボタンが押されている場合、エージェントは攻撃を実行するアクションを起こすかもしれません。
このように、Agent.LoadButtonState(ThisButtonUI)
はエージェントとボタンの間のコミュニケーションを実現するための重要な操作です。ボタンの状態をエージェントに反映させることで、ゲームやアプリケーションの動作や表示が適切に行われるようになります。
エージェントがボタンの状態を読み込むことは、肌における蚊刺されの痛みの感覚が脳に伝わるイメージに類似しています。
ボタンの状態がエージェントに伝えられることで、エージェントはその状態に基づいて適切な行動をとることができるのです。

Agent.LoadButtonState(ThisButtonUI)を記述しなかった場合
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
Agent.LoadButtonState(ThisButtonUI)を省略すると、以下のような問題が生じる可能性があります:
- ウィジェットの状態が正しく反映されない:
- LoadButtonState関数は、エージェントに対してボタンの状態を読み込むための処理を行います。
- この処理が省略されると、エージェントが正しい状態を反映していない可能性があります。
- 結果として、UIの表示や振る舞いが予期せぬものになる可能性があります。
- 間違ったウィジェットが関連付けられる:
- LoadButtonState関数によってボタンの状態が設定されることで、関連するウィジェットが適切に識別されます。
- この処理が省略されると、誤ったウィジェットが関連付けられる可能性があります。
- それによって、意図しない操作や表示が発生する可能性があります。
- エラーが発生する:
- もし後続のコードでAgent.LoadButtonState(ThisButtonUI)が必要な処理になっている場合、その処理は正しく動作せずエラーが発生する可能性があります。
- これは、依存関係が壊れるためです。
- コードの他の部分がAgent.LoadButtonState(ThisButtonUI)の実行を前提としている場合、その実行が抜けてしまうと処理の流れが崩れてしまいます。
したがって、正しい動作や表示を保証するために、このコードではAgent.LoadButtonState(ThisButtonUI)の実行が必要です。必要がない場合でも、コード全体の一貫性を保つためには一貫して省略するべきではありません。
Agent.LoadButtonState(ThisButtonUI)の役割Agent.LoadButtonState(ThisButtonUI)は、特定のエージェントに関連するボタンの状態を読み込むための関数呼び出しです。この関数は、与えられたボタンUIオブジェクト(ThisButtonUI)に関連付けられたエージェント(Agent)のボタンの状態を読み取ります。
ボタンの状態は、通常、押下状態や非アクティブ状態などを表現するためのフラグやプロパティで構成されます。
Agent.LoadButtonState()は、これらのプロパティを適切に設定することで、エージェントのボタンの状態を更新します。
その後、新しいcanvas_slotオブジェクトを作成し、このボタンの状態を反映させたキャンバス上での位置、サイズ、および表示順序などのプロパティを設定します。
Agent.LoadButtonState(ThisButtonUI)の呼び出しがないと、エージェントのボタンの状態は更新されず、意図した表示や振る舞いが得られない可能性があります。
この関数呼び出しは、正確かつ一貫したUI表示のために重要な役割を果たしています。


ボタンの状態を最新の状態にしているのですね🌸
指定されたボタンの状態を最新の状態に反映させるために、新しいcanvas_slotオブジェクトを作成し、それにボタンの位置、サイズ、表示順序などのプロパティを設定します。これにより、キャンバス上でのボタンの表示が現在の状態に合わせて更新されます。
つまり、ボタンの状態を反映させることで、ユーザーがボタンの最新の状態を視覚的に認識できるようになります。
例えば、ボタンが有効な状態であれば、それを示すようなデザインや配置がされ、ボタンが無効化された場合はそれが反映された表示が行われます。
したがって、新しいcanvas_slotオブジェクトを作成し、ボタンの状態を反映させることは、ユーザーに最新の情報や状態を提供し、一貫性のあるユーザーエクスペリエンスを実現するために重要な処理です。
【イメージ】
想像してください、あなたがオンラインショッピングのウェブサイトの開発者であり、商品の表示に関するUIを設計しています。各商品には在庫の情報(たとえば、数量や販売状態)があります。
Agent.LoadButtonState(ThisButtonUI)は、各商品に関連する在庫情報を読み込む役割を果たします。
その後、新しい商品の表示エリアを作成し、商品の位置、サイズ、表示順序などのプロパティを設定します。たとえば、販売終了の商品は他の商品よりも下に表示する設定などがあります。
これにより、在庫が変更されたり、販売状態が更新された場合に、商品の表示が適切に更新されます。Agent.LoadButtonState(ThisButtonUI)を省略すると、正しい在庫情報が反映されず、商品の表示が正しくないものになる可能性があります。
つまり、Agent.LoadButtonState()は、商品の在庫情報を読み込んで商品の表示を制御し、ユーザーに正確な在庫状況を提供する重要な役割を果たしています。
ThisWidget ではなく ThisButtonUI を指定している理由
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
ThisWidget ではなく ThisButtonUI を指定している理由は、ボタンの状態を読み込むために関連するウィジェットを特定するためです。この場合、ボタンUI (ThisButtonUI) は特定のボタンを表し、そのボタンに関連するウィジェットが保存されます。
ThisButtonUI.ButtonWidgetPerPlayer[Agent] は、指定したエージェント (Agent) に対して関連するウィジェットを取得するための記法です。ButtonWidgetPerPlayer は特定のエージェントに対してボタンウィジェットを保存する辞書や配列のような構造を表しています。この構造を使用することで、エージェントごとに対応するウィジェットを個別に取得できます。
したがって、ThisButtonUI.ButtonWidgetPerPlayer[Agent] を使用してエージェントに関連するウィジェットを取得し、それを ThisWidget に代入しています。次に、Agent.LoadButtonState(ThisButtonUI) を使用して、エージェントに対して ThisButtonUI のボタンの状態を読み込んでいます。
このように、ThisButtonUI を使用してボタンUIと関連するウィジェットを特定することで、正確なボタンの状態を取得し、それを新しい canvas_slot オブジェクトに設定することができます。

【イメージ】
コンピュータの画面上にボタンがあると想像してみましょう。そのボタンが押されたかどうかを知りたいとします。それをするためには、ボタンに関連するウィジェットを見つける必要があります。ウィジェットにはボタンの状態に関する情報が含まれています。
たとえば、ボタンが大きなユーザーインターフェース(UI)の一部であり、各ボタンはButtonUIオブジェクトによって表されているとします。ButtonUIオブジェクトにはボタンの位置やサイズ、その他のプロパティが含まれています。
そして、同じ画面でそれぞれ異なるプレーヤーやユーザーが自分のボタンUIで遊んでいると想像してみましょう。各プレーヤーは自分のボタンを表すウィジェットを持っており、これらのウィジェットはButtonWidgetPerPlayerという構造に保存されます。ButtonWidgetPerPlayerは、各ボタンに関連するウィジェットをすべてのプレーヤーごとに追跡するためのものです。
特定のプレーヤーにおけるボタンの状態を判断するためには、関連するウィジェットを見つける必要があります。これが、ThisButtonUI.ButtonWidgetPerPlayer[Agent]を使う理由です。ここで"ThisButtonUI"は現在処理しているボタンを指し、「ButtonWidgetPerPlayer[Agent]」は特定のプレーヤー(エージェント)に関連するウィジェットにアクセスする方法です。
ウィジェットを見つけたら(ThisWidget)、エージェント(Agent)に対してLoadButtonState()メソッドを呼び出し、ThisButtonUIオブジェクトを引数として渡します。このメソッドは、ウィジェットからボタンの状態(押されているかどうか)を読み取り、表示や動作を適切に更新します。
ThisButtonUIと関連するウィジェット(ThisWidget)を使うことで、特定のプレーヤーの正しいボタンにアクセスし、その状態を正確に判断することができます。

ThisWidget(特定のウィジェット)はThisButtonUI(特定のボタン)の一部ということですね🌸
つまり、ThisWidget ではなく ThisButtonUI を指定している理由は、特定のウィジェットだけでなく、すべてのウィジェットを最新状態に更新するためにThisButtonUI が指定されているということです。

このコードでは、すべてのボタンのウィジェットを最新の状態に更新するためにThisButtonUIが指定されています。
特定のエージェントに関連するウィジェットが存在する場合、関連するThisButtonUIのボタンの状態をエージェントに読み込むためにThisButtonUIが使用されます。
このコードは、各ボタンの位置やサイズ、ウィジェットの情報を利用してcanvas_slotオブジェクトを作成し、CanvasSlotArrayに追加しています。そして、最終的にCanvasSlotArrayが関数の戻り値として返されます。
このコードの目的は、特定のエージェントに対してすべてのボタンの状態を更新し、それぞれのボタンに対応するcanvas_slotオブジェクトを作成することです。

関連するウィジェットとは
クリックすると開きます。
関連するウィジェットは、ボタンを表すオブジェクトです。ボタンを押したり、離したりする動作や状態を保持しています。各プレーヤーには、自分が操作するボタンに対応するウィジェットがあります。
ウィジェットは、ボタンの情報を保持しているため、ボタンが押されたかどうかを判断するために使われます。
たとえば、ウィジェットには「ボタンが押されている」や「ボタンが離されている」といった属性があります。
プレーヤーがボタンを押すと、ウィジェットの属性が変化し、その状態が反映されます。
具体的な例として、ボタンが「押されている」状態の場合、関連するウィジェットの属性(フラグや変数)は「true」になります。一方、ボタンが「離されている」場合、ウィジェットの属性は「false」になります。
したがって、特定のプレーヤーのボタンの状態を判断するためには、そのプレーヤーに関連付けられたウィジェットを見つける必要があります。
ウィジェットの属性を調べることで、ボタンが押されたかどうかを正確に判断できます。
関連するウィジェットは、ボタンの状態を管理しているオブジェクトや要素です。
ウィジェットはボタンの外見や振る舞いを制御するために存在し、その中にはボタンの状態を表す属性や変数が含まれています。

ThisSlot := canvas_slot:の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
「ThisSlot := canvas_slot:」は、新しいスロットオブジェクトを作成するコードです。
まず、「ThisSlot」は、新しく作成されるスロットオブジェクトの変数名です。この行では、新しいスロットオブジェクトを作成し、その情報を「ThisSlot」変数に代入しています。
次に、作成されるスロットに関連する情報が設定されます。
「Offsets := margin{…}」は、スロットの位置とサイズを示す「margin」オブジェクトを作成し、それを「Offsets」というプロパティに代入しています。
「margin」オブジェクトは、上端の位置(Top)、左端の位置(Left)、下端の位置(Bottom)、右端の位置(Right)を指定することで、スロットの位置とサイズを定義します。
「ZOrder := 0」は、「ZOrder」というプロパティに値0を代入しています。これは表示の順序を制御するもので、複数の要素が重なって配置される場合に、表示する順番を決めるための値です。ここでは、値0を設定しています。
「SizeToContent := ThisButtonUI.SizeToContent」は、「SizeToContent」というプロパティに、ボタンのコンテンツに応じて自動的にサイズを調整するための設定を行っています。
これにより、ボタンの内容に合わせて最適なサイズが自動的に決定されます。この値は、「ThisButtonUI.SizeToContent」という変数から取得されます。
「Widget := ThisWidget」は、「Widget」というプロパティに「ThisWidget」という変数を代入しています。これは、スロットに関連するウィジェット(ボタンなどの要素)を指定するもので、スロットに表示される具体的な要素を設定します。
この行は、新しいスロットオブジェクトを作成し、位置やサイズ、表示順序、サイズの自動調整設定、ウィジェットへの参照などを指定するために使用されます。

ThisButtonUI.ButtonPositionでThisButtonUIが使える理由&ButtonSizeとは
クリックすると開きます。
Top := ThisButtonUI.ButtonPosition.Y
の行は、ThisButtonUI
という変数で参照されるボタンの位置情報から、上端の位置(Top)を取得するためのコードです。
このコードは、ボタンの位置情報がThisButtonUI
という変数で表され、その中にButtonPosition
というプロパティがあります。
ButtonPosition
は、ボタンの位置を示すための座標データを持っています。この座標データのY成分が、ボタンの上端に対応する位置を表しています。
したがって、Top := ThisButtonUI.ButtonPosition.Y
は、ThisButtonUI
から取得したボタンの位置データのY成分を、上端の位置(Top)に設定しています。
このように、ThisButtonUI
はボタンの特定のインスタンスを指し示しており、そのボタンの属性やデータにアクセスするために使用されています。
【ButtonSizeの定義】
vector2の詳細
クリックすると開きます。
vector2 structは、2次元のベクトルを表すためのデータ構造です。ベクトルとは、座標空間内の点を表すために使用される量であり、位置や方向を表現することができます。
vector2 structは、以下の2つの浮動小数点数(float)のデータメンバ(プロパティ)を持っています:
- X:
- ベクトルの水平方向の成分を示す浮動小数点数です。
- X軸の値を表します。
- Y:
- ベクトルの垂直方向の成分を示す浮動小数点数です。
- Y軸の値を表します。
これらのプロパティは、ベクトルの各成分の値を保持します。
たとえば、ベクトル(2.0, 3.0)はX成分が2.0であり、Y成分が3.0であることを表します。
vector2 structは、ゲームやグラフィックスプログラミングなどで頻繁に使用されます。
例えば、2Dのオブジェクトの位置や速度を表現したり、ベクトルの計算(足し算、引き算、スカラー倍など)を行ったりする際に利用されます。

canvas_slot structとは
クリックすると開きます。
canvas_slot structは、キャンバスウィジェットに対するスロット(配置枠)を表すための構造体(struct)です。
canvas_slot structは以下のデータメンバ(プロパティ)を持っています:
- Anchors(anchors):
- 余白(マージン)の境界と親要素との間のウィジェットのサイズ変更方法を定義します。
- 値は0.0から1.0の範囲で定義されます。
- Offsets(margin):
- ウィジェットのサイズや位置を定義するオフセットです。
- アンカーが適切に定義されている場合、Offsets.Leftはアンカーの最小Xからの距離をピクセル単位で表し、Offsets.Bottomはアンカーの最大Yからの距離をピクセル単位で表します。
- これにより、ウィジェットのサイズを制御します。
- アンカーが適切に定義されていない場合、Offsets.LeftとOffsets.Topはウィジェットの位置を、Offsets.RightとOffsets.Bottomはウィジェットのサイズを表します。
- SizeToContent(logic):
- trueの場合、ウィジェットの望ましいサイズを使用します。
- Offsetsによって計算されたサイズは無視されます。
- Alignment(vector2):
- アライメントはウィジェットの基準点(ピボット/原点)です。
- 左上が(0.0, 0.0)で、右下が(1.0, 1.0)です。
- ZOrder(int):
- このスロットのZオーダー(重なり順)を、キャンバスパネル内の他のスロットと比較して指定します。
- 値が大きいほど最後にレンダリングされるため、上に表示されることになります。
- Widget(widget):
- このスロットに割り当てられているウィジェットです。
canvas_slot structは、キャンバスウィジェット内でウィジェットの配置情報を定義するために使用されます。
アンカー、オフセット、サイズ、アライメント、Zオーダーなどのプロパティを設定することで、ウィジェットを特定の位置やサイズに配置することができます。
これにより、キャンバスウィジェット内に複数のウィジェットを配置し、それぞれのウィジェットの位置、サイズ、表示順序を制御することができます。

margin構造体とは
クリックすると開きます。
margin structは、Widget(ウィジェット)の周囲の余白(スペース)を指定するための構造体(struct)です。
margin structは以下のデータメンバ(プロパティ)を持っています:
- Left(float):
- ウィジェットの左側の余白を表します。
- Top(float):
- ウィジェットの上側の余白を表します。
- Right(float):
- ウィジェットの右側の余白を表します。
- Bottom(float):
- ウィジェットの下側の余白を表します。
これらのデータメンバには、単位が指定されており、1.0の単位は1080p解像度における1ピクセルの幅を表します。つまり、余白の値はピクセル単位で指定されますが、ディスプレイの解像度によってスケーリングされます。
margin structを使用すると、ウィジェットの周囲に一定のスペースを設けることができます。例えば、ウィジェットの左側に余白を追加すると、そのウィジェットは左方向にスペースが空いた状態で配置されます。
このように、margin structはウィジェットの配置や間隔を調整する際に使用される重要な構造体です。
ちなみに、この記事でもマージンは使われています。
上述の「このように、margin structは~重要な構造体です。」と、この吹き出しの間がマージンですね。
このように、margin structは、Widget(ウィジェット)の周囲の余白(スペース)を指定するための構造体(struct)です。

ZOrder := 0の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
ZOrderは、表示オブジェクトの重なり順序(表示の前後関係)を決定するためのプロパティです。ZOrderが小さいほど、表示順序が前になり、他のオブジェクトよりも手前に表示されます。
具体的には、ZOrder := 0
のように設定されています。ここでは、表示順序を0に設定していますが、他のオブジェクトよりも手前に表示するために、より小さい値を指定することもできます。
たとえば、ZOrderが-1のオブジェクトは、ZOrderが0のオブジェクトよりも背後に表示されます。同じZOrderを持つ複数のオブジェクトがある場合、コード内での順序によって重なり順序が決まります。
ZOrderを使用する際には、重なり順序を考慮してオブジェクトを配置することが重要です。これにより、適切な表示の前後関係を作り出し、視覚的なレイアウトや重なりの表現を制御することができます。
このように、ZOrderはオブジェクトの表示順序を制御するためのプロパティであり、プログラミングにおいて視覚的な表現を制御する際に重要な役割を果たします。
イメージ図SizeToContent := ThisButtonUI.SizeToContentの詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
SizeToContentは、コンテンツのサイズに基づいてウィジェットのサイズを自動調整するかどうかを指定するフラグです。
具体的には、SizeToContent := ThisButtonUI.SizeToContent
のように設定されています。ここでは、ThisButtonUIのSizeToContentの値を使ってウィジェットのサイズ調整の設定を行っています。
SizeToContentには、通常は真偽値(TrueまたはFalse)が設定されます。Trueの場合、ウィジェットのサイズが自動的にコンテンツに合わせて調整されます。コンテンツの変更に応じて、ウィジェットのサイズも自動的に変更されます。
たとえば、ボタンのコンテンツがテキストであり、サイズが可変する場合、SizeToContentをTrueに設定すると、テキストの長さに応じてボタンの幅が自動的に調整されます。
一方、Falseに設定すると、ウィジェットのサイズは静的に設定され、コンテンツの変更に関係なく固定されたサイズを保持します。
SizeToContentは、ウィジェットが動的なサイズ調整が必要な場合に特に役立ちます。例えば、テキストの入力フィールドやダイアログボックスなどのウィジェットでは、文字数やコンテンツの長さに応じて自動的にサイズが調整されることが重要です。
このように、SizeToContentはウィジェットのサイズ調整を指定するためのフラグであり、プログラミングにおいてユーザーインターフェースの外観や振る舞いを制御する際に役立ちます。

Widget := ThisWidgetの詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
Widget := ThisWidget
は、指定されたウィジェット(ボタンやコンテンツ)を変数Widget
に代入する操作です。
具体的には、Widget := ThisWidget
のように設定されています。ここでは、ThisWidget
という変数(またはオブジェクト)が存在し、それをWidget
という変数に代入しています。
変数Widget
は、あるオブジェクト(この場合はウィジェット)への参照を保持します。この参照を使用すると、後続のコードでそのウィジェットに対して操作やプロパティへのアクセスができます。
例えば、Widget
がボタンを参照している場合、Widget.Click()
というコードを実行することで、ボタンがクリックされた状態になります。
また、Widget.Label
というコードを使用すると、ボタンのラベル(表示テキスト)にアクセスできます。
このように、Widget := ThisWidget
は、特定のウィジェットへの参照を変数に格納するための操作です。これにより、プログラムの他の箇所でそのウィジェットに対して簡単にアクセスできるようになります。
【イメージ】
まず、canvas_slot
オブジェクトは、まるで木工作りで使う型紙のようなものです。この型紙には、ウィジェット(例えば、ボタンやテキストボックス)を置くためのスロットがあるんです。
canvas_slot
オブジェクトの中には、Widget
という特別なスロット(箱)があります。このWidget
スロットには、別のオブジェクトであるウィジェットをセットすることができます。
Widget := ThisWidget
は、このWidget
スロットにThisWidget
という名前のウィジェットをセット(入れる)するための命令です。
ウィジェットは例えばボタンであれば、ボタンが押された時にどのような動作をするかを指定したり、テキストボックスであれば、ユーザーがテキストを入力する場所になったりします。
つまり、Widget := ThisWidget
を使って、canvas_slot
オブジェクトの中のWidget
スロットにウィジェットを設置することで、ウィジェットに対して様々な操作や動作を行う準備が整うのです。
例えば、ウィジェットをクリックしたときに特定の処理が実行されるようにしたい場合、canvas_slot.Widget.Click()
という命令を書けば、クリックしたときの動作を設定することができます。
こうして、Widget := ThisWidget
を追加することで、ウィジェットとcanvas_slot
オブジェクトが関連付けられ、ウィジェットに対する操作や動作をcanvas_slot
オブジェクトから行えるようになるのです。

ウィジェットを参照する理由
クリックすると開きます。
Widget := ThisWidget
を代入する必要がある理由は、canvas_slot
オブジェクトのWidget
プロパティがウィジェットへの参照を保持しているためです。
Widget
プロパティにウィジェットへの参照がセットされていないと、canvas_slot
オブジェクトはウィジェットを操作することができず、エラーが発生します。
Widget := ThisWidget
を代入することで、Widget
プロパティにウィジェットへの参照がセットされ、canvas_slot
オブジェクトはウィジェットを操作できるようになります。

ウィジェットの「参照」とは、プログラム内でウィジェットを特定するための情報を指します。ウィジェットは、グラフィカルユーザーインターフェース(GUI)アプリケーションにおいて、ボタン、テキストボックス、ラベルなどの要素を表現します。
ウィジェットの参照により、プログラムは特定のウィジェットとやり取りできます。
参照には、それぞれのウィジェットに固有の識別子やアドレスのようなものが含まれています。
ウィジェットの参照を変数に格納することで、その変数を使ってプログラムの他の部分から簡単に特定のウィジェットにアクセスできるようになります。
つまり、参照を通じて、プログラムはウィジェットのプロパティ(特性)やメソッド(動作)にアクセスし、制御したり、情報を取得したりすることができるのです。
要するに、ウィジェットへの参照は、プログラムが特定のウィジェットとやり取りするための手段であり、そのウィジェットに対して操作や情報の取得を行うための入り口となります。

Widget := ThisWidgetの代入は、canvas_slotに特定のウィジェットを関連付けるため
クリックすると開きます。
Widget := ThisWidget
の代入は、ThisWidget
が存在する場合にその値をcanvas_slot
オブジェクトのWidget
プロパティに設定するためのものです。
canvas_slot
は、ウィジェットを格納して表示するためのコンテナです。
Widget
プロパティには、canvas_slot
内に配置する特定のウィジェットの参照が設定されます。この参照のおかげで、canvas_slot
はウィジェットの表示を制御できます。
コードの例では、ThisWidget
には特定のエージェントに関連付けられたウィジェットが格納されることを前提としています。
そのため、ThisWidget
が存在する場合には、それをcanvas_slot
のWidget
プロパティに設定する必要があります。
canvas_slot
のWidget
プロパティにウィジェットを設定することにより、canvas_slot
はそのウィジェットの位置やサイズを参照し、適切に表示します。
また、canvas_slot
はウィジェットのイベントや状態の変化を検出して処理することもできます。
要するに、Widget := ThisWidget
の代入は、canvas_slot
に特定のウィジェットを関連付けるためのものであり、canvas_slot
がそのウィジェットを管理し、表示するために必要な手順です。
ただし、ThisWidget
が存在しない場合やButtonUI
と関連付けるウィジェットがない場合は、Widget
プロパティには何も代入されません。


ThisWidgetが存在したら代入して参照する必要があるということですね🌸
CanvasSlotArray += array{ThisSlot}の詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
CanvasSlotArray += array{ThisSlot}
は、CanvasSlotArray
という配列に対して、ThisSlot
という要素を追加するための演算です。
まず、CanvasSlotArray
は最初に空の配列として作成されます。それから、ループ処理を通じてThisSlot
が作成され、その時点でのCanvasSlotArray
の内容にThisSlot
が追加されます。
具体的には、CanvasSlotArray += array{ThisSlot}
は以下の手順で動作します:
array{ThisSlot}
は、ThisSlot
を要素とする新しい配列を作成します。- 配列の中に
ThisSlot
が一つだけ含まれています。
- 配列の中に
CanvasSlotArray += array{ThisSlot}
は、CanvasSlotArray
に新しい配列であるarray{ThisSlot}
を追加します。- これにより、
ThisSlot
がCanvasSlotArray
の最後に追加されます。
- これにより、
例えば、最初のループでThisSlot
が作成され、それがCanvasSlotArray
に追加されます。次のループで新しいThisSlot
が作成され、それがCanvasSlotArray
に追加されます。
これが繰り返されることで、ButtonUI
の要素ごとにThisSlot
が作成され、CanvasSlotArray
に追加されます。
つまり、CanvasSlotArray
はループ処理を通じて要素が順番に追加され、最終的にButtonUI
に関連するすべてのThisSlot
が含まれる配列となります。
このように、CanvasSlotArray += array{ThisSlot}
演算は、要素を配列に追加するための便利な方法です。
配列に要素を追加することで、データをまとめたり、後で取り出したり、処理したりすることができます。

【イメージ】
例えば、以下のようなButtonUI
があるとします:
ButtonUI 1:
- ButtonWidgetPerPlayer[Agent]: Widget A
- ButtonPosition: X=100, Y=200
- ButtonSize: X=50, Y=50
- SizeToContent: true
ButtonUI 2:
- ButtonWidgetPerPlayer[Agent]: Widget B
- ButtonPosition: X=300, Y=400
- ButtonSize: X=80, Y=40
- SizeToContent: false
この場合、コードではButtonUI
の要素に対してループ処理を行い、それぞれの要素に対してThisSlot
を作成し、CanvasSlotArray
に追加します。
- 最初のループでは、
ThisButtonUI
はButtonUI 1を指します。
ThisWidget
はThisButtonUI.ButtonWidgetPerPlayer[Agent]
の結果なので、Widget Aが代入されます。- 関連するウィジェットが存在するため、
Agent.LoadButtonState(ThisButtonUI)
が実行されます。 ThisSlot
は、ButtonPositionがX=100、Y=200であり、ButtonSizeがX=50、Y=50の値を持ちます。ThisSlot.Widget
には、ThisWidget
(Widget A)が代入されます。- したがって、
ThisSlot
は次のような情報を持ったcanvas_slotオブジェクトです:Offsets = margin{ Top = 200, Left = 100, Bottom = 50, Right = 50 } ZOrder = 0 SizeToContent = true Widget = Widget A
- 最後に、
CanvasSlotArray
にThisSlot
が追加されます。
- 2番目のループでは、
ThisButtonUI
はButtonUI 2を指します。
ThisWidget
はThisButtonUI.ButtonWidgetPerPlayer[Agent]
の結果なので、Widget Bが代入されます。- 関連するウィジェットが存在するため、
Agent.LoadButtonState(ThisButtonUI)
が実行されます。 ThisSlot
は、ButtonPositionがX=300、Y=400であり、ButtonSizeがX=80、Y=40の値を持ちます。ThisSlot.Widget
には、ThisWidget
(Widget B)が代入されます。- したがって、
ThisSlot
は次のような情報を持ったcanvas_slotオブジェクトです:Offsets = margin{ Top = 400, Left = 300, Bottom = 40, Right = 80 } ZOrder = 0 SizeToContent = false Widget = Widget B
- 最後に、
CanvasSlotArray
にThisSlot
が追加されます。
このように、2つのループを通じてCanvasSlotArray
に2つのThisSlot
が追加されます。
CanvasSlotArray
は次のような配列となります:
CanvasSlotArray = [
canvas_slot{
Offsets = margin{
Top = 200,
Left = 100,
Bottom = 50,
Right = 50
},
ZOrder = 0,
SizeToContent = true,
Widget = Widget A
},
canvas_slot{
Offsets = margin{
Top = 400,
Left = 300,
Bottom = 40,
Right = 80
},
ZOrder = 0,
SizeToContent = false,
Widget = Widget B
}
]
この配列には、2つのcanvas_slot
オブジェクトが含まれており、それぞれに対してボタンの位置・サイズ情報や関連するウィジェットが設定されています。
このように、CanvasSlotArray += array{ThisSlot}
を使うことで、ループを通じて生成されたThisSlot
を順番にCanvasSlotArray
に追加することができます。

+=の詳細
クリックすると開きます。
+=
は、代入演算子の一つであり、左オペランド(変数)に右オペランドの値を加算して結果を左オペランドに代入する操作を行います。要素を追加するための演算子としても使われます。
具体的には、以下のような役割を持ちます。
- 数値の加算:
+=
は数値の加算を行います。- 例えば、
x += 5
はx = x + 5
と同じ意味であり、変数x
の値に5を加えた結果をx
に再代入します。
- 例えば、
- 文字列の結合:
+=
は文字列の結合を行います。- 例えば、
str += " World"
は文字列str
に" World"を結合し、結果をstr
に再代入します。
- 例えば、
- 配列やリストに要素を追加:
+=
は配列やリストに要素を追加するために使用されます。- 例えば、
myList += array{5, 10}
は配列myList
に5と10を追加し、新しい要素を持つ配列に再代入します。
- 例えば、
先程のコード例でのCanvasSlotArray += array{ThisSlot}
では、CanvasSlotArray
という配列にThisSlot
という要素を追加しています。
ThisSlot
は新しいcanvas_slot
オブジェクトであり、CanvasSlotArray
にその要素を追加することで、CanvasSlotArray
の末尾に新しい要素が追加されます。
要素の追加には、+=
演算子が使われますが、この演算子は要素を追加するために用意された特殊な機能です。
他の演算子と同様に、+=
演算子もプログラミング言語によって異なる振る舞いをする場合があります。

array{}を記述する理由
クリックすると開きます。
CanvasSlotArray += array{ThisSlot}
のコードは、CanvasSlotArray
にThisSlot
という要素を追加するための記述です。
array{}
は、要素を格納するための空の配列(リスト)を作成するために使用されます。この記法はプログラミング言語に依存する場合がありますが、一般的な文法としてよく使われます。
array{}
の部分を省略してCanvasSlotArray += ThisSlot
と書くこともできる場合がありますが、それには次のような制限が存在します。
- 要素が1つだけの配列を追加する場合:
CanvasSlotArray += ThisSlot
と書くことはできますが、ThisSlot
が配列ではなく単一の要素(canvas_slot
オブジェクト)として解釈されるため、うまく動作しない可能性があります。
- 複数の要素を追加する場合:
CanvasSlotArray += ThisSlot1, ThisSlot2
とすることはできません。- コンパイラまたはインタープリターは、
ThisSlot1
とThisSlot2
を個別の要素として解釈しようとするため、構文エラーが発生します。
上記の理由から、一般的には要素を追加する際にarray{}
を使って要素を明示的に配列として指定します。
これにより、単一の要素や複数の要素を正しく配列に格納することができます。

return CanvasSlotArrayの詳細
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
return CanvasSlotArray
は、関数の実行結果としてCanvasSlotArray
という変数を返す部分です。
関数の目的は、特定のエージェントに関連するボタンUIの情報をもとに、canvas_slot
というオブジェクトの配列を作成することです。そして、その配列を関数の結果として返すために、最後にreturn CanvasSlotArray
が使われています。
return
キーワードは、関数の実行結果を返すための仕組みです。この場合、CanvasSlotArray
が返されます。
CanvasSlotArray
は、空のcanvas_slot
オブジェクトの配列です。この配列は、特定のエージェントに関連するボタンの情報をまとめたオブジェクト(canvas_slot
)を要素として持ちます。
関数を呼び出すと、関数の処理が実行され、CanvasSlotArray
が作成されます。そして、return CanvasSlotArray
によって、作成されたCanvasSlotArray
が関数から返されます。
関数は、特定の処理をまとめたものです。プログラム内の他の場所で関数を呼び出すと、関数内で定義された処理が実行されます。そして、関数は通常、実行結果を返します。
return
キーワードは、関数の実行結果を指定するために使用されます。関数内部の処理が終了し、関数の実行結果を返すときに使用します。
この場合、return CanvasSlotArray
は、関数の最後にありますので、関数が終了する時点で実行されます。そして、CanvasSlotArray
という変数に格納されているオブジェクトの値を関数の結果として返します。
具体的には、関数が実行されると、まずCanvasSlotArray
という空のリストが作成されます。
その後、関数の中で処理が行われ、CanvasSlotArray
に必要なデータが追加されるかもしれません。
最後に、関数がreturn CanvasSlotArray
に達すると、関数の実行が終了し、CanvasSlotArray
が関数の呼び出し元に返されます。
返されたCanvasSlotArray
は、他の部分のコードで使用することができます。
具体例として、この関数を以下のように呼び出した場合:
result = create_canvas_slots(agent)
print(result)
create_canvas_slots(agent)
は、CanvasSlotArray
という変数を返します。その結果をresult
という変数に代入しています。そして、print(result)
によって、result
が表示されます。
つまり、return CanvasSlotArray
によって、関数からCanvasSlotArray
が返され、それがresult
に代入されます。そして、result
が表示されることになります。
return CanvasSlotArrayの記述位置について(インデント)
クリックすると開きます。
ReturnCanvasSlots(Agent: agent): []canvas_slot =
# 空の canvas_slot 配列を作成する
var CanvasSlotArray: []canvas_slot = array{}
# ButtonUI の各要素に対してループ処理を行う
for(ThisButtonUI : ButtonUI):
# 特定のエージェントに関連するウィジェットが存在する場合
if(ThisWidget := ThisButtonUI.ButtonWidgetPerPlayer[Agent]):
# エージェントに対して ThisButtonUI のボタンの状態を読み込む
Agent.LoadButtonState(ThisButtonUI)
# 新しい canvas_slot オブジェクトを作成する
ThisSlot := canvas_slot:
# ボタンの位置とサイズを示す margin オブジェクトを指定する
Offsets := margin{
Top := ThisButtonUI.ButtonPosition.Y, # 上端の位置
Left := ThisButtonUI.ButtonPosition.X, # 左端の位置
Bottom := ThisButtonUI.ButtonSize.Y, # 下端の位置
Right := ThisButtonUI.ButtonSize.X # 右端の位置
}
ZOrder := 0 # 表示順序
# コンテンツに応じて自動サイズ調整するかどうか
SizeToContent := ThisButtonUI.SizeToContent
# ウィジェットへの参照
Widget := ThisWidget
# CanvasSlotArray に作成した ThisSlot を配列として追加
CanvasSlotArray += array{ThisSlot}
# CanvasSlotArray を関数の戻り値として返す
return CanvasSlotArray
return CanvasSlotArray
が左に寄り気味なのは、このコードのインデントのスタイル(ソースコードのスペースの配置方法)に基づいているためです。
このコードでは、return
文が関数ReturnCanvasSlots
の内部でインデントされていることに注目してください。インデントは、コードのブロックや階層構造を視覚的に示すために使用されます。通常、インデントは関数や条件文、ループなどのブロック内にあるコード行を表します。
この特定のコードブロックでは、return
文はfor
ループの外側にあるため、それに合わせてインデントされています。つまり、return
文はループ内ではなく、ループの外側で実行されることを表しています。
したがって、このコードではreturn
文が左に寄って表示されているのは、インデントスタイルによるものであり、コードの階層構造を反映しているためです。
まとめ
今回はUIボタンの作成方法のVerse(3)について解説しました。
お疲れさまです🍵
コツコツがんばりましょ!
僕のTwitterアカウントです。-
-
【UEFN】UIボタンの作り方(4ページ目)│Verse解説の続き
続きを見る
-
-
【UEFN】UIボタンの作り方(5ページ目)│Verse解説の続き
続きを見る