こんにちは、あすか(@aars_inc)です。
今回は、UEFNカスタム仕様のカウントダウンタイマーについて解説します。
さっそくやっていきましょう。
なお、以下のコードの解説文は、プログラミング初心者の主がなんとか調べて記述したものです。

あすか
誤りがありましたら恐縮ですm(_ _)m
カスタム仕様のカウントダウンタイマー(2)
1がまだの方は先に1を進めましょう。
>> 備忘録UEFN:カスタム仕様のカウントダウンタイマー(1)
-
-
備忘録UEFN:カスタム仕様のカウントダウンタイマー(1)
続きを見る
カウントダウンタイマーの右上に時間を表示
▼ 新しい AddedTimeWidget を作成し、RemainingTimeWidget と同じ配置値を使用しますが、カウントダウンタイマーの右上に時間を表示します。
AddedTimeWidget の [Offset (オフセット)] の [Left (左)] の余白を 50.0 に設定し、
RemainingTimeWidget の [Offset (オフセット)] の [Top (上)] の余白を 25.0 に設定します。
countdown_timer := class:
<# このブロックは、countdown_timer class のインスタンスごとに実行されます。
ここに到達した際にキャンバスを設定できます。#>
block:
set Canvas = canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeWidget
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 25.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeWidget
クリックすると開きます。
カウントダウンタイマーのレイアウトを設定するためのものです。
countdown_timer := class:
これは、カウントダウンタイマーのクラスのインスタンスを作成することを示しています。
<# このブロックは、countdown_timer class のインスタンスごとに実行されます。
ここに到達した際にキャンバスを設定できます。#>
block:
このブロックは、カウントダウンタイマーの各インスタンスが作成されるたびに実行されるもので、キャンバスの設定を行うために使用されます。
set Canvas = canvas:
これは、カウントダウンタイマーのキャンバスを作成しています。
Slots := array:
この行では、キャンバス内のスロットを配列として指定しています。
スロットはウィジェットの配置情報を保持します。
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeWidget
この部分は、AddedTimeWidget
というウィジェットをキャンバスのスロットに配置するための情報を設定しています。
Anchors
は、ウィジェットが配置される範囲を制約するために使用されます。- ここでは、縦方向の最小・最大値と横方向の最小・最大値が同じに設定されています。
Alignment
は、ウィジェットがスロット内でどのように配置されるかを指定します。Offsets
は、ウィジェットの位置を微調整するための余白(オフセット)です。- ここでは、左側に50.0の余白が設定されています。
SizeToContent
は、ウィジェットのサイズを内容に合わせて自動的に調整するかどうかを制御します。Widget
は、このスロットに配置されるウィジェットの名前です。ここでは、AddedTimeWidget
が指定されています。
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 25.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeWidget
これは、RemainingTimeWidget
というウィジェットを別のスロットに配置するための情報を設定しています。上記と似た設定が行われており、以下の点が異なります。
Offsets
の部分で、上側に25.0の余白が設定されている点が異なります。Widget
の部分で、このスロットにRemainingTimeWidget
が配置されることが指定されています。
このコードは、カウントダウンタイマーのレイアウトを設定しています。AddedTimeWidget
とRemainingTimeWidget
は、表示する内容や見た目に応じて異なるウィジェットオブジェクトを表していると想定されます。
それぞれのオフセット(余白)の値を変更することで、それぞれのウィジェットをキャンバス上で所定の位置に配置しています。
blockの詳細
クリックすると開きます。
block:
の部分は、countdown_timer
クラスのインスタンスが作成されたときに実行されるコードブロックです。
このブロック内ではキャンバスの設定が行われています。
block:
set Canvas = canvas:
この行は、Canvas
変数に canvas
を代入しています。ここで canvas
はキャンバスのオブジェクトを指しています。
Slots := array:
この行は、Slots
変数に空の配列を代入しています。Slots
はキャンバス内のスロットを管理するための配列です。
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeWidget
この部分は、canvas_slot
というスロットを作成し、キャンバスに配置するための情報を設定しています。
Anchors
は、スロットがウィンドウ内でどの範囲に制約されるかを指定します。- ここでは、縦方向と横方向ともに最小値と最大値が同じに設定されています。
Alignment
は、スロット内のウィジェットの配置方法を指定します。Offsets
は、余白(オフセット)を設定し、ウィジェットの位置を微調整します。- ここでは、上下には余白がなく、左側には 50.0 の余白が設定されています。
SizeToContent
は、ウィジェットのサイズを内容に合わせて自動調整するかどうかを制御します。Widget
は、このスロットに配置されるウィジェットの名前です。ここでは、AddedTimeWidget
が指定されています。
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 25.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeWidget
この部分は、もう一つの canvas_slot
を作成し、同様の設定でキャンバスに配置するための情報を設定しています。
上記との主な違いは、Offsets
の部分で上側に 25.0 の余白が設定されている点です。
さらに、Widget
の部分で RemainingTimeWidget
を配置するように指定されています。
この block:
のコードでは、キャンバスに2つのスロットを作成し、それぞれのスロットにウィジェットを配置しています。
設定された余白やオフセットの値は、ウィジェットを所定の位置に配置するために使用されます。
また、SizeToContent
の値が true
に設定されているため、ウィジェットのサイズは内容に合わせて自動的に調整されます。
block:
はインスタンス化の際に実行されるコードブロックです。
クラスの定義の中で block:
を使用することで、新しいインスタンスが作成されたときに特定の処理を実行することができます😌

あすか
例えば、上記のコードでは countdown_timer
クラスのインスタンスが作成されると、block:
内のコードが実行され、キャンバスの設定やスロットへのウィジェットの配置が行われます。
各インスタンスが異なる設定を持ち、同じクラスから複数のインスタンスを生成することができます。
block:
を使用することで、それぞれのインスタンス毎に異なる初期化処理を行うことができます。
canvas_slotについての詳細
クリックすると開きます。
countdown_timer := class:
<# このブロックは、countdown_timer class のインスタンスごとに実行されます。
ここに到達した際にキャンバスを設定できます。#>
block:
set Canvas = canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeWidget
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 25.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeWidget
canvas_slot
は、キャンバス内に配置されるウィジェット用のスロット(スペース)を定義するためのものです。canvas_slot
は、ウィジェットの位置、サイズ、配置などを指定するために使用されます。
具体的に、上記のコードでは2つのcanvas_slot
が定義されています。
1つ目のcanvas_slot
は、AddedTimeWidget
のためのスロットです。
以下のプロパティを持っています。
- Anchors: ウィジェットの最小と最大のアンカー位置を指定します。
- この場合、X軸の最小と最大のアンカーポイントは画面の中央に設定され、Y軸のアンカーポイントは画面の上端に設定されます。
- Alignment: ウィジェットのアライメントを指定します。
- この場合、X軸とY軸のアライメントは画面の中央(X軸は水平方向、Y軸は垂直方向)に設定されます。
- Offsets: ウィジェットの余白(オフセット)を指定します。
- SizeToContent: ウィジェットのコンテンツに合わせてサイズを調整するかどうかを指定します。
2つ目のcanvas_slot
は、RemainingTimeWidget
のためのスロットです。
以下のプロパティを持っています。
- Anchors: ウィジェットの最小と最大のアンカー位置を指定します。
- この場合、X軸の最小と最大のアンカーポイントは画面の中央に設定され、Y軸のアンカーポイントは画面の上端に設定されます。
- Alignment: ウィジェットのアライメントを指定します。
- この場合、X軸とY軸のアライメントは画面の中央(X軸は水平方向、Y軸は垂直方向)に設定されます。
- Offsets: ウィジェットの余白(オフセット)を指定します。
- SizeToContent: ウィジェットのコンテンツに合わせてサイズを調整するかどうかを指定します。
これらのプロパティを使用することで、AddedTimeWidget
とRemainingTimeWidget
がキャンバス上で正しい位置に配置されることが保証されます。
なお、ウィジェットの配置や余白の設定はデザインの要件や表示の意図によって異なる場合があります。
詳しくは、【UEFN】canvas_slot structとは?メンバーやデータなど徹底解説にて解説していますので、参考にしてください。
-
-
【UEFN】canvas_slot structとは?メンバーやデータなど徹底解説
続きを見る
Slots := array:の詳細
クリックすると開きます。
Slots := array:
の部分は、ウィジェットが配置されるキャンバス内のスロットを定義しています。array
は配列を意味し、ここではスロットのリストを表しています。
具体的には、各スロットの定義をcanvas_slot:
のブロックで行います。
このブロックは各スロットのプロパティを指定します。
以下にcanvas_slot:
ブロック内のプロパティを解説します。
Anchors
: - ウィジェットがキャンバス内でどの位置にアンカーされるかを指定します。
- ここでは、X軸とY軸のアンカーの最小と最大の位置を
Minimum
とMaximum
で指定しています。
Alignment
: - ウィジェットのキャンバス内でのアライメント(配置位置)を指定します。
- ここでは、X軸とY軸のアライメントを
vector2
で指定しています。
Offsets
: - ウィジェットの余白(オフセット)を指定します。
- 余白は上下左右のマージンによって設定します。
- ここでは
margin
を使用し、上下左右の余白を指定しています。
SizeToContent
: - ウィジェットのコンテンツに合わせてサイズを自動調整するかどうかを指定します。
true
であれば自動調整されます。
Widget
: ウィジェットの種類やインスタンスを指定します。- ここでは
AddedTimeWidget
やRemainingTimeWidget
が指定されています。
以上のプロパティを適切に設定することで、各スロット内にウィジェットが配置され、指定された位置やサイズで表示されるようになります。
Slots := array:を記述しないとどうなるの?
Slots := array:
を記述しなかった場合、キャンバス内にウィジェットが配置されないため、表示されるものがなくなります。
Slots := array:
を記述することで、各スロットの定義を含む配列を指定しているため、それぞれのスロット内にウィジェットが配置されるようになります。
ウィジェットが配置されないと、ユーザーに何も表示されず、予定された機能や情報の提供も行えません。
したがって、Slots := array:
を記述しない場合、キャンバス上にウィジェットを配置する機能がなくなり、UIの一部が欠落することになります。
正しい設定を行うためには、スロットとウィジェットの関連付けをSlots := array:
によって指定する必要があります。
そもそもウィジェットを設置するには、スロットが必要であるということですね。

あすか
Anchors := anchors:の詳細
クリックすると開きます。
「Anchors := anchors:」というコードは、ウィジェットがキャンバス内で配置される位置やサイズを指定するためのアンカー(Anchor)の情報を設定するためのコードです。
アンカーは、要素がウィンドウや親要素に対してどの位置やサイズで相対的に配置されるかを示すための指標です。
具体的には、ウィジェットの四隅や中心などの位置を基準に指定します。
Anchors := anchors:
の部分では、anchors
という変数(またはプロパティ)にアンカーの情報を格納しています。
アンカーの指定方法は具体的なプログラミング言語やフレームワークによって異なりますが、一般的には以下のような指定方法があります(具体的な値は場合により異なります):
- 左上隅(Top-Left)のアンカー位置:(0.0, 0.0)
- 右上隅(Top-Right)のアンカー位置:(1.0, 0.0)
- 左下隅(Bottom-Left)のアンカー位置:(0.0, 1.0)
- 右下隅(Bottom-Right)のアンカー位置:(1.0, 1.0)
- 中央(Center)のアンカー位置:(0.5, 0.5)
このように、アンカーはX軸とY軸の相対的な位置を表す値で指定されます。たとえば、(0.0, 0.0)はウィンドウや親要素の左上隅を、(1.0, 1.0)は右下隅を基準にした位置となります。
具体的なウィジェットの配置やサイズに関する詳細な指定は、アンカーを使用しながら他のプロパティ(例:オフセット、サイズなど)と組み合わせて行われます。
アンカーを適切に設定することで、ウィジェットが想定した位置やサイズで表示されるようになります。
Anchors := anchors:を記述しないとどうなるの?
Anchors := anchors:
の記述がない場合、ウィジェットの配置やサイズが自動的に設定されず、予期しない結果が起こる可能性があります。
アンカーの設定によってウィジェットの配置が調整されます。アンカーが正しく設定されていない場合、ウィジェットが期待した位置やサイズで表示されず、次のような問題が生じる可能性があります。
- ウィジェットの位置が固定されない:
- アンカーを指定しない場合、ウィジェットの配置はデフォルトの挙動に依存します。
- その結果、ウィンドウや親要素の変更によってウィジェットの位置が意図しないように移動する可能性があります。
- ウィジェットのサイズが変わらない:
- アンカーを設定せずにウィジェットを配置すると、ウィジェットのサイズもデフォルトのままになります。
- その結果、ウィジェットがコンテンツの長さに合わせて自動的に伸縮しないなど、レイアウトの一貫性や柔軟性に問題が生じる可能性があります。
- オーバーラップや重なり:
- アンカーを正しく設定しないと、複数のウィジェットが重なったり、互いに干渉して表示されたりする可能性があります。
- これによって、ユーザーにとって情報の見逃しや操作の困難さが生じる可能性があります。
したがって、ウィジェットの正しい配置やサイズ指定をするためには、適切なアンカーの設定が重要です。
アンカー情報を明示的に記述することで、ウィジェットが意図した位置に正しく表示されるようになります。
どうしてcanvas_slot:の定義が2つもあるの?
クリックすると開きます。
canvas_slot:の定義が2つある理由は、countdown_timerが2つのウィジェットを表示するためです。
1つは追加された時間のウィジェット、もう1つは残りの時間のウィジェットです。各ウィジェットは、独自のキャンバススロットを持っています。
追加された時間のウィジェットは、キャンバスの左側に表示されます。
ウィジェットのサイズは、ウィジェットの内容に合わせて調整されます。ウィジェットは、AddedTimeWidgetクラスによって作成されます。
残りの時間のウィジェットは、キャンバスの右側に表示されます。
ウィジェットのサイズは、ウィジェットの内容に合わせて調整されます。
ウィジェットは、RemainingTimeWidgetクラスによって作成されます。
canvas_slot:~AddedTimeWidget版
クリックすると開きます。
このコードは、キャンバス内に配置されるウィジェットの表示方法を指定しています。
時間のウィジェット
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeWidget
canvas_slot:
: canvas_slot
は、キャンバス内にウィジェットを配置するための特殊なスロットを指定します。Anchors := anchors:
: ウィジェットのアンカーの情報を設定します。
Minimum := vector2{X := 0.5, Y := 0.05}
: アンカーの最小値を設定します。- この場合、X軸方向のアンカーはキャンバスの幅の50%の位置に、Y軸方向のアンカーはキャンバスの高さの5%の位置に設定されます。
Maximum := vector2{X := 0.5, Y := 0.05}
: アンカーの最大値を設定します。- この場合、X軸方向のアンカーはキャンバスの幅の50%の位置に、Y軸方向のアンカーはキャンバスの高さの5%の位置に設定されます。
Alignment := vector2{X := 0.5, Y := 0.0}
: ウィジェットのアンカー位置に対するアラインメント(配置)を指定します。- この場合、ウィジェットはX軸方向で中央(50%)に配置され、Y軸方向では上端に配置されます。
Offsets := margin{Top := 0.0, Left := 50.0, Bottom := 0.0, Right := 0.0}
: ウィジェットのアンカーポイントからのオフセット(位置の微調整)を指定します。- この場合、ウィジェットは上下左右に0のオフセットを持ち、左方向に50のオフセットが付加されます。
SizeToContent := true
: ウィジェットのサイズを内容に合わせて自動調整するかどうかを指定します。- ここでは
true
に設定されており、ウィジェットの内容に合わせてサイズが自動的に調整されます。
Widget := AddedTimeWidget
: キャンバススロットに配置する具体的なウィジェットの種類を指定します。- この場合は
AddedTimeWidget
という特定のウィジェットが指定されています。
このコードは、キャンバス内に配置されるウィジェットの表示位置、サイズ、配置方法などを細かく指定しています。
これにより、画面上の特定の位置にウィジェットが表示され、それに関連する要素(アンカー、アラインメント、オフセットなど)が設定されます。
SizeToContent等のcanvas_slot structは以下の記事を参考にしてください。
>> 【UEFN】canvas_slot structとは?メンバーやデータなど徹底解説
-
-
【UEFN】canvas_slot structとは?メンバーやデータなど徹底解説
続きを見る
アンカーとアラインメントの違い
クリックすると開きます。
ウィジェットのアンカーとアラインメントは、ウィジェットの配置やサイズ調整に関連して使用される2つの異なる概念です。
アンカーは、ウィジェットが配置される座標の位置を指定します。
アンカー通常、ウィンドウや親要素に対する相対的な位置で指定されます。
例えば、ウィジェットのアンカーがウィンドウの左上隅に設定されている場合、ウィンドウのサイズが変更されてもウィジェットはウィンドウの左上隅に固定されます。
一方、アラインメントは、ウィジェット自体の内部的なコンテンツをどのように配置するかを指定します。
アラインメントは、ウィジェット内のテキストやアイコンなどの要素の相対的な位置を制御します。
例えば、ウィジェットのアラインメントが水平方向に中央、垂直方向に上端に設定されている場合、ウィジェット内のコンテンツは水平方向の中央に配置され、垂直方向では上端に配置されます。
アンカーとアラインメントは関連していますが、いくつかの異なる役割を持っています。
アンカーはウィジェットの配置を決定し、親要素に対する相対的な位置を指定します。一方、アラインメントはウィジェット内のコンテンツの配置方法を指定し、ウィジェット内での要素の相対的な位置を制御します。
要約すると、アンカーはウィジェットの配置を親要素に対して相対的に指定し、アラインメントはウィジェット内のコンテンツの位置を制御します。
噛み砕くと
アンカーは、ウィジェットが配置される基準点を指定します。これは、ウィンドウや親要素内の相対的な位置を示すものです。
たとえば、ウィジェットのアンカーが左上に設定されている場合、ウィンドウの左上隅にウィジェットが配置されることになります。
一方、アラインメントは、ウィジェット内のコンテンツ(テキストや画像など)の配置方法を指定します。
つまり、ウィジェット内の要素がどのように整列するかを制御します。
例えば、ウィジェットの横方向のアラインメントを中央に設定すると、ウィジェット内のコンテンツは水平方向に中央に配置されます。
アンカーとアラインメントの関係は、ウィジェットを親要素内で適切に配置するために使用されます。アンカーは基準点を指定し、アラインメントはその基準点からの相対的な配置方法を制御します。
【例】
ウィジェットのアンカーが親要素の左上隅に設定され、横方向のアラインメントが中央、縦方向のアラインメントが上端に設定されている場合、ウィジェットは親要素内で左上隅を基準にして、横方向に中央、縦方向に上端に配置されます。
つまり、アンカーは基準点を決め、アラインメントはその基準点からの相対的な位置を指定することで、ウィジェットを適切に配置するのに役立ちます。

あすか
アラインメントとオフセットの違い
クリックすると開きます。
アラインメントとオフセットは、ウィジェットの配置や位置制御において異なる概念です。
アラインメントは、ウィジェット内の要素(テキストや画像など)の相対的な配置方法を指定します。
具体的には、要素がウィジェット内でどの位置や方向に配置されるかを制御します。
例えば、横方向のアラインメントを中央に設定すると、ウィジェット内の要素は水平方向に中央に配置されます。
オフセット(または位置オフセット)は、ウィジェットの位置を微調整するために使用されます。
ウィジェットが配置される基準点からの相対的な位置のシフトを指定する感じですね。
例えば、ウィジェットのアンカー位置が左上隅に設定されている場合、水平方向のオフセットを正の値に設定すれば、ウィジェットは左に移動します。
同様に、垂直方向のオフセットを正の値に設定すれば、ウィジェットは上に移動します。
ですので、アラインメントは要素同士の相対的な配置方法を制御し、オフセットはウィジェットの位置を微調整するために使用されます。
つまり、アラインメントは要素の相対的な配置方法を指定し、オフセットはウィジェットの位置を微調整するために使用されます。

あすか
【噛み砕くと】
アラインメントはウィジェット内の要素の相対的な配置方法を制御するために使用されるということ。
ウィジェット内の要素を中央に配置したり、左寄せにしたりするなど、要素同士の位置関係を調整します。
一方、オフセットはウィジェットそのものの位置を微調整するために使用されます。
ウィジェットの配置基準点からの相対的なシフトを指定することで、ウィジェットの位置を微調整できるわけです。
つまり、アラインメントはウィジェット内の要素同士の位置関係を制御し、オフセットはウィジェット全体の位置を微調整するために使用されます。
canvas_slot:~RemainingTimeWidget版
クリックすると開きます。
下記のコードは、ウィジェットの配置と表示方法を設定するためのパラメータを含んだデザインの一部を表しています。
以下では、各パラメータとその意味を解説します。
残り時間のウィジェット
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.05}
Maximum := vector2{X := 0.5, Y := 0.05}
Alignment := vector2{X := 0.5, Y := 0.0}
Offsets := margin{Top := 25.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeWidget
- Anchors (アンカー):
- 最小値 (Minimum): ウィジェットの左下隅のアンカーポイントを示します。
- この値は、ウィジェットの相対的な配置を指定します。
- 今の例では、ウィジェットの横方向のアンカーは画面の中央(X = 0.5)に、縦方向のアンカーは画面の上端(Y = 0.05)に設定されています。
- 最大値 (Maximum): ウィジェットの右上隅のアンカーポイントを示します。
- 今の例では、ウィジェットの最大値も最小値と同じく、中央と上端に設定されています。
- Alignment (アラインメント):
- X: ウィジェット内の要素が横方向にどのように配置されるかを指定します。
- 今の例では、X値(横方向のアラインメント)が0.5で設定されているため、要素はウィジェット内で中央に配置されます。
- Y: ウィジェット内の要素が縦方向にどのように配置されるかを指定します。
- 今の例では、Y値(縦方向のアラインメント)が0.0で設定されているため、要素はウィジェット内で上端に配置されます。
- Offsets (オフセット):
- Top: ウィジェットの上端からの縦方向のオフセットを指定します。
- 今の例では、上端からのオフセットが25.0と設定されているため、ウィジェットは上方向に25ピクセル分移動します。
- Left: ウィジェットの左端からの横方向のオフセットを指定します。
- 今の例では、左端からのオフセットが0.0で、ウィジェットは水平方向に移動しません。
- Bottom: ウィジェットの下端からの縦方向のオフセットを指定します。
- 今の例では、下端からのオフセットが0.0と設定されているため、ウィジェットは垂直方向に移動しません。
- Right: ウィジェットの右端からの横方向のオフセットを指定します。
- 今の例では、右端からのオフセットが0.0で、ウィジェットは水平方向に移動しません。
- SizeToContent (コンテンツに合わせてサイズ調整するかどうか):
- true: ウィジェットのサイズが内包するコンテンツに合わせて自動的に調整されます。
- false: ウィジェットのサイズが固定されます。
- Widget (ウィジェット):
- RemainingTimeWidget: ウィジェットに表示する具体的なコンテンツやビューを示す名前や参照です。
2秒間表示の新たな関数を作成
▼ AddedTimeWidget の値を更新し、ウィジェットを再び非表示にする前にコールアウトを 2 秒間表示する「AddedTimeCallout()
」という名前の新しい関数を作成します。
AddRemainingTime()
で AddedTimeCallout()
を呼び出します。
AddRemainingTime(Time : float) : void =
set RemainingTime += Time
# 時間が追加された際に UI を即座に更新して、より優れたプレイヤー フィードバックを実現します。
UpdateUI()
# シンプルなコールアウトを起動して、追加される時間を表示します。
spawn:
AddedTimeCallout(Time)
AddedTimeCallout(Time : float)<suspends> : void =
if:
PlayerUI := MaybePlayerUI?
IntTime := Int[Time]
then:
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
AddedTimeWidget.SetText(AddedTimeText(IntTime))
Sleep(2.0)
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
AddRemainingTime(Time : float) : void =
set RemainingTime += Time
# RemainingTime(残り時間)にTime(追加される時間)を足す
# 時間が追加された際に UI を即座に更新して、より優れたプレイヤー フィードバックを実現します。
UpdateUI()
# シンプルなコールアウトを起動して、追加される時間を表示します。
spawn:
AddedTimeCallout(Time)
# AddedTimeCallout関数を生成し、追加される時間を表示します。
AddedTimeCallout(Time : float)<suspends> : void =
if:
PlayerUI := MaybePlayerUI?
IntTime := Int[Time]
then:
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
# AddedTimeWidgetの表示を可視化します。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
# AddedTimeWidgetにIntTime(整数化されたTime)のテキストを設定します。
Sleep(2.0)
# 2秒間待機します。
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
# AddedTimeWidgetの表示を非表示にします。
クリックすると開きます。
このコードは、ウィジェットと関数を使用してタイマー機能を実装し、タイマーに追加された時間をプレイヤーにフィードバックするための処理を行います。
AddedTimeWidget
"AddedTimeWidget"は、追加された時間を表示するためのUIウィジェットです。
このウィジェットは非表示状態で初期化されています。
AddRemainingTime(Time : float) : void
"AddRemainingTime"関数は、引数で指定された時間を元の残り時間に追加し、それに伴うUIの更新と追加時間を表示するコールアウトを行います。
RemainingTime += Time
:UpdateUI()
:- UIを即座に更新するための関数です。
- タイマーのUI表示を更新するための処理
spawn: AddedTimeCallout(Time)
:AddedTimeCallout
関数を非同期に実行します。- 追加された時間を表示するコールアウトを行います。
AddedTimeCallout(Time : float) : void
"AddedTimeCallout"関数は、引数で渡された時間を表示するコールアウトを行います。
PlayerUI := MaybePlayerUI?
:- "MaybePlayerUI"というオブジェクトが存在する場合、それを"PlayerUI"変数に代入します。
- この処理は、プレイヤーのUIへアクセスするための前提です。
IntTime := Int[Time]
:- 追加された時間を整数値に変換し、"IntTime"変数に代入します。
- これは表示する時間を整数で表示するための処理です。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
:- "AddedTimeWidget"を可視状態に設定します。
- これにより、ウィジェットが表示されます。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
:- "AddedTimeWidget"のテキストを、整形された追加時間の値で更新します。
Sleep(2.0)
:- 2秒間の待機処理を行います。
- これにより、追加時間を表示する時間が得られます。
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
:- "AddedTimeWidget"を非表示状態に設定します。
- これにより、ウィジェットが非表示になります。
このコードの目的は、タイマーに追加された時間をプレイヤーにフィードバックすることです。
AddRemainingTime関数は、追加された時間を受け取って残り時間を更新し、UIを即座に更新します。
さらに、追加された時間を表示するコールアウトを表示し、2秒間表示した後に非表示にします。これにより、プレイヤーに追加された時間を視覚的に伝えます。
AddRemainingTimeの関数の定義の詳細
クリックすると開きます。
このコードは、AddRemainingTime
という関数を定義しています。
AddRemainingTime(Time : float) : void =
set RemainingTime += Time
# RemainingTime(残り時間)にTime(追加される時間)を足す
AddRemainingTime
関数は、Time
という浮動小数点数型のパラメータを受け取ります。- 関数内の行
set RemainingTime += Time
は、RemainingTime
という変数にTime
を加算しています。
【記述理由】
このコードの目的は、残り時間 (RemainingTime
) に指定された時間 (Time
) を追加することです。
この機能は、ゲームやアプリなどのタイマーがあり、プレイヤーが追加の時間を獲得した際に、残り時間を更新するために使用されることが想定されています。
例えば、ゲーム内でプレイヤーがあるアイテムを取得すると、追加の時間を獲得できるとします。その場合、この関数を呼び出して残り時間を更新し、プレイヤーに追加のプレイ時間を提供することができます。
プログラミング初心者にとって理解しやすくするために、次のような例を考えてみましょう。
RemainingTime = 10.0 # 初期の残り時間は10秒
AddRemainingTime(4.5) # 4.5秒が追加される
print(RemainingTime) # 最終的な残り時間は14.5秒
上記の例では、初期の残り時間が10秒であり、AddRemainingTime
関数に4.5を渡しています。関数は残り時間に4.5を加算し、最終的な残り時間は14.5秒になります。
このように、関数呼び出しによって時間が追加され、変数の値が更新されることが確認できます。
プログラミングでは、このように関数を使用することで、特定の処理を再利用できるため、コードの簡潔さと再利用性を高めることができます。
UpdateUI()とspawnの詳細
クリックすると開きます。
# 時間が追加された際に UI を即座に更新して、より優れたプレイヤー フィードバックを実現します。
UpdateUI()
# シンプルなコールアウトを起動して、追加される時間を表示します。
spawn:
AddedTimeCallout(Time)
# AddedTimeCallout関数を生成し、追加される時間を表示します。
このコードは、時間が追加された際にUIを即座に更新し、プレイヤーに優れたフィードバックを提供するための処理を行います。
# 時間が追加された際に UI を即座に更新して、より優れたプレイヤー フィードバックを実現します。
UpdateUI()
UpdateUI()
関数は、UIを更新するための処理を実行します。- この処理は、時間が追加された際に呼び出され、プレイヤーに対して情報の更新や視覚的な反応を提供するために使用されます。
# シンプルなコールアウトを起動して、追加される時間を表示します。
spawn:
AddedTimeCallout(Time)
# AddedTimeCallout関数を生成し、追加される時間を表示します。
spawn:
という行は、非同期のプロセス(コルーチンやスレッドなど)を生成するためのものであり、コールアウトの表示を待つことなく処理を進めることができます。AddedTimeCallout(Time)
は、Time
を引数としてAddedTimeCallout
関数を起動します。- この関数は、追加される時間を表示するためのコールアウトを生成します。
【記述理由】
このコードの目的は、時間が追加された場合にプレイヤーにリアルタイムなフィードバックを提供することです。
UpdateUI()
関数は、プレイヤーのUIを更新するための処理を呼び出しています。
これにより、追加された時間やそれに関連する情報が即座に表示され、プレイヤーにわかりやすいフィードバックを提供します。
spawn:
ブロック内のコードは、コールアウトを生成して追加される時間を表示するための処理です。
このコールアウトは非同期に実行されるため、他の処理と同時に実行されることができ、プレイヤーに視覚的なフィードバックを提供します。
プログラミングにおいて、UIの更新やフィードバックの提供は、ユーザーエクスペリエンスの向上とタスクの可視化に重要な役割を果たします。
AddedTimeCallout(Time :関数の定義の詳細
クリックすると開きます。
下記のコードは、フォートナイト(Fortnite)内のプレイヤーインタフェースにおいて、指定された浮動小数点数の「Time」を整数化し、それを表示するためのウィジェットを可視化した後、2秒間待機するためのコードです。
AddedTimeCallout(Time : float)<suspends> : void =
if:
PlayerUI := MaybePlayerUI?
IntTime := Int[Time]
then:
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
# AddedTimeWidgetの表示を可視化します。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
# AddedTimeWidgetにIntTime(整数化されたTime)のテキストを設定します。
Sleep(2.0)
# 2秒間待機します。
AddedTimeCallout(Time : float)<suspends> : void =
AddedTimeCallout
という関数を定義します。Time
という名前の float
型のパラメータを受け取ります。<suspends>
は、この関数が非同期の処理(待機可能)を含んでいることを示すキーワードです。: void
は、この関数が戻り値を返さないことを示します。
if:
PlayerUI := MaybePlayerUI?
MaybePlayerUI
の値を PlayerUI
に割り当てています。MaybePlayerUI
はもしかしたら存在しないかもしれない値であり、この行はその存在を確認しています。
:=
は変数への代入を示す演算子です。
IntTime := Int[Time]
Time
の値を整数に変換し、IntTime
に割り当てます。Int[Time]
は Time
を整数に変換する演算子です。
then:
- 条件文の真の場合のブロックの始まりを示すキーワードです。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
AddedTimeWidget
の可視性を変更して、表示します。widget_visibility.Visible
はウィジェットの可視性を示す値です。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
AddedTimeWidget
のテキストを IntTime
の値に設定します。AddedTimeText(IntTime)
は、IntTime
の値をテキストに変換する関数です。
Sleep(2.0)
- 2秒間の待機を行います。プログラムの実行を一時停止します。
Sleep
関数は指定された秒数の待機を行う関数です。
このコードの目的は、AddedTimeCallout
関数が呼び出された際に、フォートナイトのプレイヤーインタフェースに「Time」の値を整数化したテキストを表示することです。また、表示後に2秒間待機します。
非同期処理が必要な理由
AddedTimeCallout関数では、特定のプロセスを実行した後に2秒間待機してから再び別のプロセスを実行しています。
この待機時間中に他の処理を実行したり、プログラムの実行を続行したりする必要があります。
そのため、AddedTimeCallout関数には非同期処理が必要です。
非同期処理を使用することで、AddedTimeCallout関数が2秒間待機する間に、他の処理が実行されることが可能になります。
例えば、他のUIの更新やイベントの処理などが行われることで、より効率的なプログラムの動作とスムーズなユーザー体験が実現できます。
したがって、AddedTimeCallout関数には非同期処理を実現するためのキーワードが必要であり、そのキーワードを使用することでコンパイラーに処理の一時停止と再開を伝えることができます。
<suspends>の詳細
クリックすると開きます。
<suspends>
という用語は、プログラミングで非同期処理を示すために使われます。非同期処理は、プログラムが他のタスクを実行しながら、待機中の処理を一時停止(サスペンド)できる仕組みです。
非同期処理では、特定の操作が完了するのを待つために、他のプログラムの動作が一時的に中断されることがあります。
非同期処理を行う関数やメソッドは、<suspends>
という注釈を使用してその性質を明示することがあります。
関数に<suspends>
注釈が付いている場合、その関数が非同期的に実行される可能性があることを示します。
関数が非同期的に実行される場合、呼び出し元のコードは関数を呼び出した後でも実行を一時停止し、その関数が完了するのを待つことがあります。
非同期処理は、ネットワークリクエストの送信、データベースアクセス、ファイルの読み込みなど、時間のかかるタスクを実行する場合に特に役立ちます。
非同期処理を使用することで、プログラムは他の操作を進めながら、待機中の処理を効率的に処理することができます。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)の詳細
クリックすると開きます。
このコードの行は、AddedTimeWidget
というウィジェットの可視性を設定するための処理です。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
AddedTimeWidget
は、プログラムで使用されている特定のウィジェットの名前です。- ウィジェットは、ユーザーインターフェース(UI)に表示される要素やコンポーネントのことを指します。
SetVisibility
は、AddedTimeWidget
の可視性を設定するメソッド(関数)です。- このメソッドは、ウィジェットの表示または非表示を制御します。
widget_visibility.Visible
は、可視性を示す定数です。- この場合は、
Visible
という値を指定しているため、AddedTimeWidget
は可視状態になります。
この行の目的は、AddedTimeWidget
を表示可能な状態にすることです。
つまり、プレイヤーがプログラムを実行すると、AddedTimeWidget
が画面に表示されるようになります。
SetVisibilityメソッドを使う理由
クリックすると開きます。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
コードでは、AddedTimeWidget
オブジェクトのSetVisibility
メソッドを呼び出しています。
このメソッドは、ウィジェットの表示状態を変更する処理です。
メソッドを使用する必要がある理由は、ウィジェットの表示状態を変更する処理が複雑なためです。
この処理をコードに直接書くと、コードが長くなり、読みにくくなります。
メソッドを使用すると、処理をコードから切り離して、別のファイルに記述することができます。
これにより、コードが短くなり、読みやすくなります。
また、メソッドを使用すると、処理を再利用することができます。このメソッドを呼び出すことで、ウィジェットの表示状態を変更する処理を簡単に実行することができますね。
このように、メソッドを使用すると、コードを短く、読みやすく、再利用しやすくすることができます。
(widget_visibility.Visible)の詳細
クリックすると開きます。
widget_visibility
列挙型は、ユーザーインターフェース(UI)におけるウィジェットの表示状態を指定するために使用されます。
widget_visibility
列挙型は、次の値(列挙子)を持ちます。
Visible
(表示): - ウィジェットが表示され、レイアウト上でスペースを占めています。
- つまり、ユーザーがウィジェットを見ることができます。
Collapsed
(非表示): - ウィジェットは非表示であり、レイアウト上でスペースを占めません。
- つまり、ユーザーはウィジェットを見ることができません。
- ただし、ウィジェットが非表示になっても、レイアウトの他の要素がそのスペースを使用する可能性があります。
Hidden
(非表示):- ウィジェットは非表示であり、レイアウト上でスペースを占めています。
- つまり、ユーザーはウィジェットを見ることができませんが、ウィジェットが占めるスペースは他の要素に影響する可能性があります。
これらの列挙子は、ウィジェットの可視性を制御するために使用されます。
プログラム内で widget_visibility
の値を適切に設定することで、ユーザーが見ることができるかどうか、ウィジェットがレイアウトにスペースを占めるかどうかを制御できます。
例えば、SetVisibility
メソッドにて Visible
を指定すると、ウィジェットは表示され、ユーザーが操作可能な状態になります。
一方、Collapsed
を指定すると、ウィジェットは見えなくなり、スペースを占有しないため、他の要素がその領域を使用できます。
Hidden
を指定すると、ウィジェットは見えない状態でありながら、スペースを占有しています。
これにより、プログラム内でウィジェットの表示状態を柔軟に制御することができます。
詳しくは【UEFN】widget_visibility列挙型とは?特徴を徹底解説にて解説していますので、参考にしてください。
-
-
【UEFN】widget_visibility列挙型とは?特徴を徹底解説
続きを見る
SetVisibilityメソッドを使う理由
クリックすると開きます。
then:
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
# AddedTimeWidgetの表示を可視化します。
上記のコードでは、AddedTimeWidget
というウィジェットの表示を可視化するために、SetVisibility
というメソッドが使用されています。
詳細は以下のとおりです。
- ウィジェットの表示状態を制御するための汎用性:
- メソッドを使用することにより、同じコードを再利用できます。
SetVisibility
メソッドは、他のウィジェットでも同様の表示状態を設定する際にも使用できます。- このように、メソッドを使用することでコードを効率的に記述できます。
- 内部処理のカプセル化:
- メソッドは関連する処理をひとまとめにするため、コードの可読性が向上します。
SetVisibility
メソッド内部では、実際の表示設定を行う箇所や関連するエラーチェックなどの詳細な処理が抽象化されています。- そのため、メソッドの呼び出し元では内部処理の詳細を気にする必要がなく、シンプルかつ理解しやすいコードを書くことができます。
- インターフェースの一貫性:
- メソッドを使用すると、ウィジェットの表示状態を制御するためのインターフェースが統一されます。
SetVisibility
メソッドは、AddedTimeWidget
によって提供されるようになっています。- これにより、他の開発者がコードを扱う際に、ウィジェットの表示状態を設定するためにどのメソッドを使用するか一目でわかるようになります。
メソッドを使用することにより、コードの再利用性、可読性、インターフェースの一貫性が向上します。
AddedTimeWidget.SetVisibilityの間の.の意味
クリックすると開きます。
AddedTimeWidget.SetVisibility(widget_visibility.Visible)
における.
は、オブジェクト指向プログラミングにおいて、オブジェクト(ここではAddedTimeWidget
)のメンバー(属性やメソッド)にアクセスするために使用される演算子です。
.
は「ドット演算子」とも呼ばれ、オブジェクトとそのメンバーを結びつける役割を果たします。
具体的には、AddedTimeWidget
というオブジェクトのメンバーであるSetVisibility
メソッドを呼び出しています。
ここで、AddedTimeWidget
は特定の型やクラスのインスタンスであり、そのオブジェクトが持つ属性やメソッドを指定して操作することができます。
.
を使ってオブジェクトに付随するメンバーを指定することで、そのメンバーの処理や値の取得・設定などを行います。
例えば、AddedTimeWidget
がボタンを表すオブジェクトであり、そのボタンをクリック可能にするためのSetVisibility
メソッドが存在する場合、AddedTimeWidget.SetVisibility(widget_visibility.Visible)
は、AddedTimeWidget
オブジェクトのSetVisibility
メソッドを呼び出して、ボタンの可視性を設定することを意味します。
つまり、.
はオブジェクトとそのメンバーを紐付け、特定のメンバーにアクセスするための演算子です。これにより、オブジェクト指向プログラミングでは、オブジェクトが持つデータや振る舞いを組織化し、効果的に操作できるようになります。
AddedTimeWidget.SetText(AddedTimeText(IntTime))の詳細
クリックすると開きます。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
# AddedTimeWidgetにIntTime(整数化されたTime)のテキストを設定します。
上記のコードは、ウィジェット(グラフィカルな要素)であるAddedTimeWidgetに、整数形式に変換された時間をテキストとして表示するための設定を行っています。
以下にコードの解説をするので、初心者の方にもわかりやすく説明します。
IntTime
: - 変数
IntTime
には、時間を表す値が格納されていると仮定します。
AddedTimeText(IntTime)
: AddedTimeText
という関数にIntTime
を渡して呼び出します。- この関数は、渡された時間を整数形式に変換し、テキストとして返すものとします。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
: AddedTimeWidget
というオブジェクト(ウィジェット)のSetText
メソッドを使用して、ウィジェットにテキストを設定します。- 具体的には、前のステップで得られた整数形式の時間をテキストに変換した結果を設定します。
このコードは、時間を表す値を整数形式に変換し、その変換結果をテキストとして特定のウィジェットに表示するための手順を表しています。
応用すれば、他のウィジェットやデータ型にも同様のアプローチを適用できます。
計算式の論理
AddedTimeWidget.SetText(AddedTimeText(IntTime))
# AddedTimeWidgetにIntTime(整数化されたTime)のテキストを設定します。
上記のコードは、あるウィジェット(AddedTimeWidget)に時間を表す整数値(IntTime)をテキストとして設定するための処理を行っています。
以下にコードの論理を解説します。
IntTime
: IntTime
は、時間を表す値(float型)を整数値に変換したもの。
AddedTimeText(IntTime)
: AddedTimeText
という関数にIntTime
を引数として渡し、関数を呼び出します。- この関数は、渡された時間を整数形式に変換し、テキストとして返します。
- 例えば、もし
IntTime
の値が3であれば、AddedTimeText(3)
を呼び出して実行します。 AddedTimeText
関数の内部で、IntTime
を整数形式に変換し、その結果をテキストとして返します。
AddedTimeWidget.SetText(AddedTimeText(IntTime))
: AddedTimeWidget
というオブジェクト(ウィジェット)のSetText
メソッドを使用して、ウィジェットにテキストを設定します。AddedTimeText(IntTime)
は、前のステップで得られた整数形式の時間をテキストに変換した結果です。AddedTimeWidget.SetText(...)
では、...
の部分には前のステップで得られたテキストが入ります。- つまり、このコードは、ウィジェットに時間を表す整数値をテキストとして表示するために、そのウィジェットの
SetText
メソッドを使用してテキストを設定しています。
したがって、このコードの論理は、時間を整数値からテキストに変換し、それを特定のウィジェットに設定するという処理の流れを表しています。
このような手順を実行することで、時間を整数値ではなくテキストとして表示することができます。
SetTextメソッドの詳細
クリックすると開きます。
SetTextメソッドは、ウィジェット(画面上の要素)にテキストを設定するためのメソッドです。具体的には、ウィジェットに表示されるテキストを指定したテキストに変更します。
詳細は以下のとおり。
AddedTimeWidget
: AddedTimeWidget
は、テキストを表示するウィジェットの名前または参照です。- このウィジェットは、例えば画面上のラベルやテキストボックスのような要素です。
AddedTimeText(IntTime)
: AddedTimeText
という関数は、整数値を受け取り、その整数値をテキスト形式に変換する役割を担います。- この関数は、整数値をテキストに変換するためのカスタムの変換ルールを実装することができます。
- 例えば、整数値が「5」の場合、「5秒」というテキストに変換するといった具体的な処理を追加することができます。
AddedTimeText(IntTime)
の結果を引数として、SetText
メソッドが呼び出されます。- この引数には、テキストに変換された整数値が渡されます。
SetText
メソッドは、引数として渡されたテキストをウィジェットに設定します。- つまり、ウィジェットの表示が、変換されたテキストに変更されます。
- これにより、ウィジェットが整数値の時間をテキストとして表示する役割を果たします。
例えば、ウィジェットが「RemainingTime」という名前のテキストラベルであり、経過時間が整数値である場合、AddedTimeWidget.SetText(AddedTimeText(IntTime))
は、経過時間を整数値からテキストに変換し、その結果を「RemainingTime」ラベルに表示することを意味します。
ウィジェットに文字を表示させたいときは、SetTextメソッドを使いましょう。

あすか
AddedTimeText:IntTimeが整数化したテキストを返す関数である理由
クリックすると開きます。
「AddedTimeText:IntTimeを整数化したテキストを返す関数」と定義したコードは、以下のとおり。
AddedTimeText<localizes><private>(AddedTime : int) : message = " +{AddedTime}!"
このコードは、AddedTimeという名前の整数を引数として受け取り、それに「 +」を付けて、整数化したテキストを返す関数を定義しています。
具体的には、AddedTimeText()関数に整数値を入力として渡すと、整数化されたテキストを返します。
たとえば、AddedTimeText()関数に123を入力すると、「 +123!」というテキストを返します。
Sleep(2.0)~t_visibility.Hidden)までの詳細
クリックすると開きます。
Sleep(2.0)
# 2秒間待機します。
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
# AddedTimeWidgetの表示を非表示にします。
詳細は以下のとおりです。
Sleep(2.0)
: Sleep
は、一定の時間を待機するための関数またはメソッドです。- 引数に指定された時間(ここでは2.0秒)だけ、プログラムの実行を一時停止します。
- つまり、次の行の処理に進む前に、指定した時間だけ待機します。
- この場合は、2秒間待機します。
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
: AddedTimeWidget
は、操作対象のウィジェットの名前または参照です。SetVisibility
は、ウィジェットの表示状態を変更するためのメソッドです。- 引数として渡された
widget_visibility.Hidden
は、ウィジェットの非表示を示します。 - つまり、
AddedTimeWidget
の表示が非表示(見えない状態)になります。
このコードの意味をまとめると、以下のようになります。
Sleep(2.0)
によって、プログラムは2秒間停止します。この間、何も操作せずに待機します。- 2秒の待機が終了した後、
AddedTimeWidget
の表示が非表示になります。
widget_visibility.Hiddenについての詳細は以下で解説しています。
>> 【UEFN】widget_visibility列挙型とは?特徴を徹底解説
SetVisibility機能の詳細
クリックすると開きます。
SetVisibility
機能は、ウィジェットの表示または非表示を切り替えるための関数(メソッド)です。
この関数を使用することで、ウィジェットをユーザーに表示するか非表示にするかを制御することができます。

あすか
技術的な詳細は以下のとおり。
関数の概要
- 関数名: SetVisibility
- 関数の種類: メソッド(オブジェクト指向プログラミングにおいて、クラスに関連付けられた関数)
- 呼び出し方法: オブジェクト.メソッド名(引数)
- 返り値の型: void(戻り値なし)
引数
- InVisibility: widget_visibility型
- ウィジェットの表示状態を示す列挙型で、以下のいずれかの値を指定します。
widget_visibility.Visible
:ウィジェットを表示します。widget_visibility.Hidden
:ウィジェットを非表示にします。
このように、SetVisibility
関数はウィジェットを表示または非表示にするための関数であり、引数のInVisibility
に指定した値によって挙動が変わります。
ちなみに、SetVisibilityは、Set(設定)、Visibility(可視性)で、
可視性の設定という意味です😌

あすか
今回メソッドとして使用
AddedTimeWidget.SetVisibility(widget_visibility.Hidden)
は、AddedTimeWidget
オブジェクトのSetVisibility
メソッドです。
メソッドは、オブジェクトの機能であり、オブジェクトの状態を変更するために使用されます。
一方、関数は、入力値を受け取って出力値を返すものです。
AddedTimeWidget.SetVisibility
メソッドは、ウィジェットの可視性を設定するというオブジェクトの機能であり、入力値も出力値もありません。

あすか
Sleep関数の詳細
クリックすると開きます。
Sleep関数は、指定された時間(秒)だけ待機した後に再開するための関数です。
引数
- Seconds: float型の場合
- Seconds = 0.0 の場合
- 次のTick/フレーム/アップデートまで待機します。
- Seconds = Inf の場合
- 無期限に待機し、キャンセルされるまでコールバックが行われません(例:raceを介したキャンセルなど)。
- Seconds < 0.0 の場合
- 即座に完了し、他の非同期式に譲らずに処理を続行します。
上記の引数によって、Sleep関数の挙動が変化します。
また、関数の特性や効果を示す属性とエフェクトについては以下のとおり。
エフェクト
- suspends:
- 関数が非同期であることを示し、関数の本体に非同期コンテキストを作成します。
- varies:
- 同じ入力に対して関数の出力が常に同じであるとは限らないことを示します。
- また、関数の振る舞いは、それを含むパッケージの新しいバージョンでは同じであることが保証されないことも示します。
- transacts:
- 関数によって実行されるアクションをロールバックできることを示します。
- 変更可能な変数(var)が書き込まれる場合には、transactsエフェクトが必要です。
- no_rollback:
- デフォルトのエフェクトであり、関数によって実行されるアクションは元に戻せないため、失敗コンテキストで使用できません。
- このエフェクトは手動で指定することはできません。
suspends(非同期処理)
出典:O-TWO BLOG
suspendsエフェクトは、関数が非同期であることを示しています。
つまり、Sleep関数の呼び出し時に、関数の実行が一時停止し、他の処理が実行されることがあります。

あすか
このような場合、Sleep関数の実行中に他のタスクが進行し、並行して処理が行われることがあるので頭の片隅に入れておきましょう。
プレイテスト
出典:公式ドキュメント
プレイテストを行うと、カウントダウンが 30 から開始し、タイマーが 0 になるまで毎秒更新されて、その後カウントダウンが UI から消えます。
プレイヤーがボタンとやり取りすると、カウントダウンに 20 秒が追加され、追加された時間を示すコールアウトが 2 秒間表示されます。
公式ドキュメント
カウントダウンタイマーの終了を知らせる
このチュートリアルでは、ボタンの仕掛けの InteractedWithEvent を使用して、プレイヤーがいつボタンを押したかを知り、カウントダウン タイマーにさらに時間を追加しました。
しかし、コードに何かが起こったときに、他のユーザーがそれを把握するために使用できるカスタム仕様のイベントを独自に作成することもできます。
この例では、カスタム仕様のイベントの次の動作を使用する方法を示しています。
Signal():この関数は、イベントを待っているものすべてに、イベントが発生したことを知らせます。
Await():この非同期関数は、イベントが通知されるまで、この関数を含むコンテキストの実行をブロックします。
この例では、エンド ゲームの仕掛けを起動できるようにカウントダウンの終了したことを通知するイベントをカウントダウン タイマーに追加します。
公式ドキュメント
このチュートリアルでは、カウントダウンタイマーにさらに時間を追加するためにボタンを使用し、ボタンが押された時刻を把握します。
また、コードに何か特定のイベントが発生したときに、他のユーザーにそれを通知するためのカスタム仕様のイベントを作成する方法も紹介されています。
イベントの作成方法は以下のとおり。
Signal()
関数:- この関数は、イベントが発生したことを待っているすべての要素に通知します。
Await()
関数:- この非同期関数は、イベントが通知されるまで、それを含むコンテキストでの実行を一時停止します。
上記の要点をまとめると、カウントダウンタイマーが終了したことを通知するためのイベントをカウントダウンタイマーに追加する方法が示されています。
このカスタムイベントを使うと、エンドゲームのトリガーポイントとして利用できるわけですね。
具体的には、ボタンが押された時刻を把握しながら、カウントダウンタイマーの終了を待ち、終了したことを通知するためのカスタムイベントを作成します。
countdown_timerにイベントフィールドを追加
▼ 下記のコードは、カウントダウン終了のためのイベントを追加するための手順を示しています。
CountdownEndedEvent : event() = event(){}
クリックすると開きます。
countdown_timer
クラスに「CountdownEndedEvent」という名前のイベントフィールドを追加します。
- イベントフィールドとは、イベントが発生したことを他の部分に通知するための仕組みです。
- カウントダウンタイマーの終了を通知するために新しいイベントフィールドを作成します。
- イベントフィールドは、特定のイベントが発生したときに実行されるコードを他の部分に伝える役割を果たします。
CountdownEndedEvent: event() = event(){}
という行は、イベントフィールドの定義を示しています。
CountdownEndedEvent
という名前のイベントフィールドを作成しています。CountdownEndedEvent
は、パラメータを取らずにイベントを表すために使用されるパラメトリック型です。event(){}
は、イベントフィールドを初期化するための構文です。- ここでの初期化は、クラスのインスタンス化を模倣するため、
event()
内にはコンストラクタのような初期化コードは含まれていません。
このように、カウントダウン終了のためのイベントフィールドを作成することで、他の部分にカウントダウンの終了が通知されます。
このイベントフィールドを使用することで、例えばエンドゲームのトリガーポイントとして利用することができます。
プログラミングにおいてイベントやイベントフィールドを使用することは一般的です。特定の条件やアクションが発生したことを他の部分に通知するために使われます。
計算式の論理
CountdownEndedEvent : event() = event(){}
上記のコードは、カウントダウンの終了を通知するためのカスタムイベント「CountdownEndedEvent」を定義しています。
event()
は、イベントを表す特殊な形式の型です。
この型は、イベントが発生したことを通知するために使用されます。
ここでは、CountdownEndedEvent
という名前の変数を定義し、event(){}
で初期化しています。
イベント変数CountdownEndedEvent
は、特定の条件が満たされた時にイベントが発生することを示します。
このイベントは他のコードに通知するために使用されるため、他のコードはこのイベントを待ち、発生したことを知ることができます。
具体的には、カウントダウンのタイマーが終了した時に、CountdownEndedEvent
のSignal()
メソッドを呼び出すことで、イベントが発生します。
これにより、他のコードがそのイベントを検知して特定のアクションを実行することができます。
このようにして、CountdownEndedEvent
を使用することで、カウントダウンの終了を他のコードに通知することができます。
イベントフィールドとは
クリックすると開きます。
イベントフィールドは、イベントが発生したことを他の部分に通知するために使用されます。
通常、イベントが発生すると、それに関連するイベントハンドラー(あるいはイベントリスナー)と呼ばれる特別な関数やコードが実行されます。
イベントフィールドは、このようなイベントハンドラーがアタッチされるポイントです。
イベントフィールドには、イベントが発生したことを通知するために必要な情報やデータ、パラメータが格納されます。
例えば、「CountdownEndedEvent」というイベントフィールドがあった場合、このフィールドはカウントダウンが終了したことを他の部分に通知する役割を果たします。
イベントフィールドには、追加のデータを含めることもできます。
例えば、カウントダウンが終了した時刻や終了したカウントダウンの識別子などの情報を格納することができます。
イベントフィールドは、イベントドリブンアーキテクチャやイベント駆動プログラミングにおいて重要な概念です。
イベントが発生したことを他の部分に通知し、応答や処理を実行するために使用されます。
event(t) クラスの詳細
クリックすると開きます。
event(t) クラスは、パラメータ付きのイベントを表すクラスであり、並行するタスク間の調整を行うためのシンプルなメカニズムを提供します。
このクラスでは、次のような用途に使用することができます。
Await
関数によって、タスクを一時停止させ、このイベントの発生を待機します。- 別のタスクが
Signal
関数を呼び出すことで、このイベントを発生させ、待機中のタスクを FIFO (先入れ先出し) の順序で再開させます。
このクラスは、UEFNevent(t) クラスとしても知られており、パラメータ付きのペイロードを持つイベントによって実装された、繰り返し発生するイベントを表します。
また、awaitable
、subscribable
、またはその両方 (listenable) と一緒に使用することもできます。
クラスは以下のインターフェースを公開しています。
signalable(payload)
: - ペイロードを持つイベントをシグナルできるようにするパラメータ付きのインターフェース。
- awaitable、subscribable、またはその両方と使用できます (listenable)。
awaitable(payload)
: - 待機可能なペイロードを持つイベントを表すパラメータ付きのインターフェース。
- signalable と対応します。
このクラスには関数が存在し、データメンバーはありません。
機能は以下のとおり。
Await
関数: - 現在のタスクを一時停止させ、別のタスクが Signal を呼び出すまで待機します。
- Signal の別の呼び出し中に Await が呼び出された場合でも、タスクは一時停止し、次の Signal 呼び出し時に再開します。
Signal
関数: - 待機中のタスクを一斉に再開します。
- タスクは一時停止した順序で再開されます。
- 各タスクは可能な限り作業を実行し、ブロッキング呼び出しに遭遇すると次の一時停止中のタスクに制御を渡します。
このように、event(t) クラスを使用することで、パラメータ付きのイベントをシグナルし、待機中のタスクを再開させることができますね。

あすか
event(t) クラスを使うと、ある条件が満たされたときに通知が必要な場合に便利です。
このクラスを使って、待機中のタスクを制御し、必要なタイミングで再開させることができます。
具体的には、タスクAが Await
を呼び出してカウントダウンが終わるのを待ち、別のタスクBが Signal
を呼び出すと、タスクAは再開されます。
これによって、タスクBとタスクAは連携して処理を進めることができます。
このクラスは、他のタスクを待ち合わせる機能を提供し、タスク間の順序を制御することができます。
それにより、複数のタスクが同時に動作する必要がある場合でも、適切なタイミングで処理を連携できますね。
event(t)クラスのtは値の型?
event(t) クラスでの「t」は型を表します。
この型は、生成されるイベントのペイロード(データ)の型を指定するために使用されます。
具体的には、tは例えば整数や文字列、オブジェクトなどのデータ型を指定することができます。
イベントが実際に発生した際には、指定された型のデータを含んだイベントが生成されます。
"event()"は、パラメトリック型(parametric type)と呼ばれる型です。
パラメトリック型は、値やオブジェクトのインスタンスではなく、クラスやインターフェースを表現するために使用されます。
非同期のカウントダウンを実行する関数
▼ RunCountdown()
を更新して CountdownEndedEvent
に通知し、ループから出る前に他のコードにカウントダウンが終了したことを知らせます。
RunCountdown()<suspends> : void =
# TimerTickPeriod を使ってループします。
# UI も毎回更新されます。
loop:
Sleep(TimerTickPeriod)
set RemainingTime -= TimerTickPeriod
UpdateUI()
# タイマーの終了
if (RemainingTime <= 0.0):
if (UI := MaybePlayerUI?):
UI.RemoveWidget(Canvas)
CountdownEndedEvent.Signal()
break
RunCountdown()<suspends>: void =
# カウントダウンを実行する非同期関数です。実行中に一時停止することがあります。
# TimerTickPeriod を使ってループします。
# カウントダウンを進めるために指定の間隔で処理が実行されます。
loop:
# TimerTickPeriod の間一時停止します。
Sleep(TimerTickPeriod)
# 残り時間を更新します。
set RemainingTime -= TimerTickPeriod
# UI を更新します。
UpdateUI()
# タイマーの終了を確認します。
# 残り時間が0以下になった場合に処理が実行されます。
if (RemainingTime <= 0.0):
# もしプレイヤーのUIが存在する場合、UIからカウントダウンウィジェットを削除します。
if (UI := MaybePlayerUI?):
UI.RemoveWidget(Canvas)
# CountdownEndedEvent にイベントを通知します。
CountdownEndedEvent.Signal()
# ループから抜けて関数の実行を終了します。
break
クリックすると開きます。
下記のコードは、非同期のカウントダウンを実行する関数を示しています。
指定された時間間隔でループを繰り返し、時間をカウントダウンしていきます。
ループ内では、一定時間停止してから残り時間を更新し、UIを更新します。
もし残り時間が0以下になった場合は、UIからカウントダウンウィジェットを削除し、カウントダウン終了のイベントを通知して関数の実行を終了します。
RunCountdown()<suspends> : void =
# TimerTickPeriod を使ってループします。
# UI も毎回更新されます。
loop:
Sleep(TimerTickPeriod)
set RemainingTime -= TimerTickPeriod
UpdateUI()
# タイマーの終了
if (RemainingTime <= 0.0):
if (UI := MaybePlayerUI?):
UI.RemoveWidget(Canvas)
CountdownEndedEvent.Signal()
break
RunCountdown()<suspends>: void =
RunCountdown()
という関数は、カウントダウンを実行します。<suspends>
という表記は、この関数が実行中に一時停止(非同期)することがあることを示しています。
また、関数の返り値(戻り値)の型が void
と指定されているため、この関数は何も返さないことを意味します。
loop:
この行は、ループを開始するためのマークです。ループ内の処理は、この行の後から始まります。
Sleep(TimerTickPeriod)
Sleep(TimerTickPeriod)
は、一時的にプログラムの実行を一定時間停止するためのコマンドです。
TimerTickPeriod
の値に指定した時間だけ処理を停止します。
これにより、指定の時間間隔で処理を継続的に実行するための待ち時間を作ります。
set RemainingTime -= TimerTickPeriod
set RemainingTime -= TimerTickPeriod
は、RemainingTime
変数から TimerTickPeriod
の値を引いて、RemainingTime
変数の値を更新しています。
つまり、残り時間から指定の時間間隔を減算し、残り時間を更新しています。
UpdateUI()
UpdateUI()
は、ユーザーインターフェース(UI)を更新するための関数です。
この関数を呼び出すことで、表示されているカウントダウンの数値やテキストなどのUIを更新します。
if (RemainingTime <= 0.0):
if (RemainingTime <= 0.0)
は、RemainingTime
の値が0以下かどうか判定する条件文です。
もし RemainingTime
の値が0以下の場合、以下の処理が実行されます。
if (UI := MaybePlayerUI?):
MaybePlayerUI?
は、プレイヤーのUI(ユーザーインターフェース)を取得するためのオブジェクトや変数を表しています。
UI := MaybePlayerUI?
という行は、MaybePlayerUI?
の値を UI
という変数に代入するという意味です。
もし MaybePlayerUI?
の値が存在する場合(真の値を持つ場合)、以下の処理が実行されます。
UI.RemoveWidget(Canvas)
UI.RemoveWidget(Canvas)
は、UIからカウントダウンウィジェット(画面上の要素)を削除するためのコマンドです。
これにより、画面上のカウントダウン表示を取り除きます。
CountdownEndedEvent.Signal()
CountdownEndedEvent.Signal()
は、CountdownEndedEvent
というイベントを通知するためのコマンドです。
他の部分のプログラムにカウントダウンの終了を通知するために使用します。
break
break
は、ループから抜け出すためのキーワードです。この行に到達すると、現在のループが終了し、関数の実行も終了します。
UI.RemoveWidget(Canvas)のCanvasの記述理由
クリックすると開きます。
このコードの中での Canvas
は、おそらくUIの一部を表す特定の要素やコンテナを指しています。
個別のコンテキストやプログラムの他の部分がわからないため、具体的な Canvas
の意味や用途については確認できませんが、一般的なUI開発の場合、Canvas
はグラフィックスや要素の配置を管理するために使用されるコンテナ要素を指すことが多いです。
このコードでは、タイマーの終了時に Canvas
を削除していることが示されています。
おそらく、Canvas
は表示されているUIの一部であり、タイマーが終了するとそれを削除する必要がある状況だと推測されます。
UIが複数の要素やコンポーネントで構成されている場合、特定の要素を特定するためにその要素の名前または参照を使用する必要があります。
したがって、このコードでは Canvas
という特定のUI要素を削除するために UI.RemoveWidget(Canvas)
と記述されているのです。
CountdownEndedEvent.Signal()の()をつける意味
クリックすると開きます。
Signal()
は、おそらくイベントの通知やシグナルの発行を示すメソッドまたは関数です。()
は、メソッドを呼び出すために使用される構文であり、ここでは Signal
メソッドが引数なしで呼び出されていることを意味しています。
イベントを発行するメソッドが返り値を持たない場合、一般的には ()
を付けて呼び出されます。これにより、メソッドが発火されることが示されます。
UI.RemoveWidget(Canvas)のUIの要素
クリックすると開きます。
このコードにおける UI
は、おそらくプレイヤーのユーザーインターフェース(UI)を参照する変数です。このコードは、タイマーの終了時にUIに関する処理を行っているようです。
UI.RemoveWidget(Canvas)
は、UI上から特定のウィジェット(Canvas)を削除するために使用されています。具体的なコンテキストやプログラムの他の部分がわからないため、Canvas
が何を表しているかは確認できませんが、おそらく画面上の特定の要素やコンポーネントを指していると思われます。
UIを操作するために UI
という変数を使用し、その中の特定の要素(この場合は Canvas
)を削除しているのは、プログラムの設計や構造によるものです。UIに関連する処理や操作を行う場合、対象のUI要素を特定するために UI
変数を使用し、その要素の操作を行います。
したがって、このコードでは、UIの特定の要素を削除するために UI.RemoveWidget(Canvas)
という記述が必要になるのです。
【重要】Sleepがない場合に想定される状況
クリックすると開きます。
想定されることは以下のとおり。
- カウントダウンの進行速度の制御がない:
- Sleepがない場合、ループ内の処理が瞬時に実行されます。
- これにより、カウントダウンが瞬時に減少し、UIの更新が高速に行われる可能性があります。
- ユーザーはこの速度に追いつけず、正確なカウントダウンを視覚的に追跡することが困難になる場合があります。
- プロセッサのリソース消費が高まる可能性がある:
- Sleepがないため、ループが連続して実行されるため、CPUリソースを連続的に消費することになります。
- これは、実行中のプログラムが大量のプロセッシングパワーを不必要に使用することにつながります。
- イベントの発生が過剰になる可能性がある:
- Sleepがない場合、ループ内の処理が高速に実行され、イベントの発生が過剰になるかもしれません。
- たとえば、カウントダウンが終了したことを示すイベントが一瞬で複数回発生する可能性があります。
Sleepの使用により、一定の時間間隔を持つループ処理が行われるため、上記の問題や潜在的なパフォーマンス上の問題を回避することができます。
時間間隔の役目を担っていると?
はい、正確です。Sleep関数の使用により、指定した時間間隔(TimerTickPeriod)ごとにカウントダウンが進行し、秒数が減少します。
具体的には、以下のようになります。
- TimerTickPeriodで指定した時間間隔ごとにプログラムが一時停止します(Sleep(TimerTickPeriod))。
- その後、RemainingTime(残り時間)からTimerTickPeriodの値を減算します(set RemainingTime -= TimerTickPeriod)。
- UIを更新して、残り時間の変更を反映します(UpdateUI())。
この処理をSleep関数を利用して繰り返すことで、指定した時間間隔ごとに秒数が減っていくカウントダウンが実現されるわけです。
TimerTickPeriodの詳細
クリックすると開きます。
"TimerTickPeriod"は、時間の単位(通常はミリ秒)で表される一定の時間間隔を指す変数または定数の名前です。具体的には、タイマーイベントが発生する頻度を制御するために使用されます。
タイマーは、一定の時間間隔でイベントを発生させる仕組みです。プログラム内でタイマーを設定し、そのタイマーイベントが発生する頻度を制御するために、TimerTickPeriodという変数(または定数)を使います。
"TimerTickPeriod"の値は、具体的な要件に基づいて設定されます。
例えば、1000ミリ秒(1秒)の間隔でタイマーイベントを発生させる場合には、TimerTickPeriod = 1000と設定します。
この場合、Sleep(TimerTickPeriod)の行は、プログラムを1秒間停止するという意味になります。
TimerTickPeriodは、プログラムのタイミングや処理の調整に使用される時間間隔を表す変数です。
具体的な意味は、プログラムのコンテキストによって異なる場合があります。
TimerTickPeriodの間一時停止する理由
クリックすると開きます。
"TimerTickPeriod"の間に一時停止する理由は、プログラム内のタイミングや処理の調整に関連しています。
使用目的は以下のとおり。
- タイミングの制御:
- 一時停止を使用することで、処理を特定の時間間隔ごとに実行することができます。
- 例えば、ゲーム内のタイマーの更新や、定期的なセンサーデータの取得など、一定のプログラムの実行間隔を確保するために使用されます。
- リソースの制御:
- プログラムが瞬時に大量のリソースを消費する場合に、一時停止を使用して制御することがあります。
- たとえば、CPU使用率を制限するために一時停止を挿入したり、インターネットへのアクセスを時間間隔で制限するために使用することもあります。
Loop and Breakの詳細
クリックすると開きます。
LoopとBreakは、プログラムで繰り返し処理を行う際に使用される制御フローの概念です。
Loop(ループ)は、一連の処理を繰り返し実行するための表現です。ループのコードブロック内の式が繰り返し実行されます。
Break(ブレイク)は、ループを終了するための制御文です。ループを途中で終了したい場合に使用します。
Loopはループの開始。
Breakはループの終了。

あすか
具体例を通じて解説します。
loop:
DoCleanSweepEmote()
上記のコードは、ループブロック内のDoCleanSweepEmote()
という式を繰り返し実行します。
このループは、最後まで再生されると始めから繰り返されます。ループブロック内の式は、ゲーム内でキャラクターが掃除をするように繰り返し実行されるイメージです。
ループブロックは、ブレイク文が実行されるまで無限に繰り返されるため、「無限ループ」とも呼ばれます。ただし、ほとんどの場合において無限ループはあまり有用ではありません。なぜなら、プログラムの進行を妨げるためです。そのため、ループを終了させる方法が必要です。
ループを終了させる方法は2つあります。
- End(終了):ブレイクまたはリターンでループを終了します。
- Suspend(一時停止):一時的にループを中断します。
また、同じループ内でこれらの方法を組み合わせることもできます。
以下の例では、ループブロック内のランダムな数値が20未満である限り、ループが繰り返されます。
loop:
# ランダムな数値を生成
RandomNumber: int = GetRandomInt(0, 100)
# ランダムな数値が20未満かをチェック
if (RandomNumber < 20):
# ループを終了
break
上記のコードでは、ランダムな数値が20未満であれば、ブレイク文でループを終了します。
LoopとBreakを使った制御フローは、繰り返し処理を効果的に制御するための手段です。ループ内で行いたい処理を指定し、必要に応じてブレイクでループを終了させることで、プログラムを柔軟に制御できます。
また、ネストされたループとブレイクを組み合わせることもできます。ネストされたループの場合、内側のループでブレイク文が実行されると、内側のループから抜けだすだけであり、外側のループは継続します。
まとめると、ループは繰り返し処理を行うためのものであり、ブレイクはループを途中で終了させるためのものであると理解してください。これにより、プログラムのフローを柔軟に制御できます。
CountdownEndedEvent.Signal()コードがない場合
クリックすると開きます。
CountdownEndedEvent.Signal()
のコードが存在しない場合、カウントダウン終了イベントはトリガーされません。カウントダウンが終了したとしても、関連する処理やイベントハンドラは実行されません。
具体的には、以下のような状況が考えられます:
def HandleCountdownEnded():
# カウントダウン終了時の処理を記述する
print("カウントダウンが終了しました!")
CountdownEndedEvent.AddHandler(HandleCountdownEnded) # イベントハンドラを登録する
# カウントダウンが実行されている場所...
# しかし、CountdownEndedEvent.Signal() の呼び出しはない
上記の例では、カウントダウン終了時のイベントハンドラを登録していますが、CountdownEndedEvent.Signal()
の呼び出しはありません。
そのため、カウントダウンが終了しても、HandleCountdownEnded
関数は実行されず、「カウントダウンが終了しました!」というメッセージは表示されません。
CountdownEndedEvent.Signal()
の呼び出しは、イベントのトリガーに必要であり、その後に登録されたイベントハンドラが実行されるようになります。
したがって、イベントの発生や処理を実現するためには、CountdownEndedEvent.Signal()
の適切なタイミングで呼び出す必要があります。
イベントハンドラとは
イベントハンドラとは、イベントが発生したときに実行されるコードのことです。
イベントハンドラは、イベント発生源に登録することができます。イベント発生源は、イベントが発生したときに、登録されているイベントハンドラを呼び出します。
たとえば、ボタンをクリックしたときに、ボタンをクリックしたことを通知するイベントが発生します。
このイベントが発生したときに、ボタンをクリックしたときに実行したいコードをイベントハンドラに記述します。
ボタンをクリックすると、イベントハンドラが実行され、コードが実行されます。
イベントハンドラは、ユーザーの操作を検出したり、データの変更を検出したり、ネットワーク通信を検出したり、さまざまなイベントを検出するために使用されます。
ハンドラの由来
ハンドラの由来は、英語の「handle」から来ています。handleは「取っ手」という意味です。
ハンドラは、イベントを扱うためのコードなので、handleという名前が付けられました。
Signalの詳細
クリックすると開きます。
CountdownEndedEvent.Signal()
は、CountdownEndedEvent
(カウントダウン終了イベント)オブジェクトの Signal
メソッドを呼び出すコードです。
Signal
メソッドは、イベントオブジェクトをトリガーするために使用されます。イベントオブジェクトが発生(トリガー)すると、関連する処理や動作が実行されます。
具体的には、CountdownEndedEvent.Signal()
を呼び出すことで、カウントダウン終了イベントが発生し、関連する処理やイベントハンドラが実行されることを意味します。
この時、プログラマーはこのイベントをキャッチし、イベントハンドラ内で特定の処理を実行することができます。
例えば、以下のようなコードが想定されます:
CountdownEndedEvent.Signal() # カウントダウン終了イベントを発生させる
def HandleCountdownEnded():
# カウントダウン終了時の処理を記述する
print("カウントダウンが終了しました!")
CountdownEndedEvent.AddHandler(HandleCountdownEnded) # イベントハンドラを登録する
# ゲームなどでカウントダウンが実行されている場所...
# カウントダウン完了時に CountdownEndedEvent.Signal() を呼び出す
上記の例では、カウントダウンが終了したタイミングで CountdownEndedEvent.Signal()
を呼び出しています。
その後、HandleCountdownEnded
関数がイベントハンドラとして設定されており、カウントダウン終了イベントがトリガーされると、「カウントダウンが終了しました!」というメッセージが表示されます。
噛み砕くと、Signal
メソッドはイベントオブジェクトに「イベントが発生したことを通知する」という意味合いがあります。
その後、イベントを捕捉するためにイベントハンドラを登録し、実際の処理を記述します。
CountdownEndedEventの詳細
クリックすると開きます。
CountdownEndedEvent
は、「カウントダウン終了イベント」という意味です。これは、プログラミングやゲーム開発の文脈で使用されるイベントの一種です。
イベントは、特定の条件やアクションが発生した際にトリガーされる通知です。
CountdownEndedEvent
は、通常、カウントダウンが指定された時間まで進み、タイマーやカウンターが終了したことを示すイベントです。
例えば、ゲーム内のタイムアタックモードで、制限時間のカウントダウンが終了したときにゲームオーバーとする場合、CountdownEndedEvent
を使用して「カウントダウン終了イベント」を処理します。
このイベントが発生すると、アクションやスクリプトが実行され、ゲームオーバー画面が表示されたり、結果が表示されたりする可能性があります。
プログラミング初心者の方は、イベントはゲーム内で何が起こるかを通知するものだと考えてください。
この場合、「カウントダウン終了イベント」は、時間制限が終了したことを知らせるイベントです。
SignalとAwait関数の詳細
クリックすると開きます。
Signal()
とAwait()
は、非同期プログラミングにおけるイベント通知の仕組みです。
Signal()
関数は、イベントが発生したことを待っているオブジェクトに対して信号を送信します。
これにより、待機中のオブジェクトがイベントが発生したことを知ることができます。
通常、イベントが発生した後にSignal()
関数を呼び出すことで、待機中のオブジェクトに信号を送信します。
これにより、ブロックされていた処理を再開させることができます。
Await()
関数は、イベントが通知されるまで、非同期関数を含むコンテキストの実行を一時停止します。
これにより、イベントの発生を待つことができます。通常、Await()
関数は非同期関数の中で使用され、イベントが通知されるまで処理を一時停止します。
イベントが発生した後、非同期関数の実行を再開させることができます。
これらの関数は、非同期プログラミングにおいて、複数のタスクやスレッド間での情報の同期や通信に使用されます。
特に、非同期処理で発生するイベントの待機と通知に役立ちます。

あすか
RemoveWidget関数の詳細
クリックすると開きます。
RemoveWidget
関数は、指定されたウィジェットを含むスロット(領域)を削除する機能です。
この関数の具体的な解説を以下に示します。
関数名: RemoveWidget
アクセス修飾子: public
戻り値の型: void
(値を返さないことを表す)
パラメータ:
Widget
(ウィジェット): widget
型の値として、削除したいウィジェットのオブジェクトが渡されます。
関数の機能:
RemoveWidget
関数は、指定されたウィジェットを含むスロットを削除します。
ウィジェットは、画面上の特定の領域やパネルに配置された要素を表します。例えば、メニューバー、ボタン、テキストボックスなどのUI要素がウィジェットとして機能します。
この関数を使用すると、特定のウィジェットを持つスロットが削除され、それによってUI上から関連する要素も削除されます。たとえば、ボタンが表示されているスロットを削除すれば、そのボタンも同時に削除されます。
Removeの意味
Remove は、英語で「取り除く」「削除する」という意味です。
コンピューター用語では、データベースからレコードを削除したり、ファイルやディレクトリを削除したりすることを指します。
キャンバス・スロット・ウィジェットの関係性
クリックすると開きます。
キャンバスは、ウィジェットを配置する領域です。
スロットは、ウィジェットをキャンバスに配置するための場所です。
ウィジェットは、スロットに配置することで、キャンバスに表示されます。
スロットは、ウィジェットをキャンバスに配置するための場所です。キャンバスのレイアウトを制御するために使用されます。特徴として、ウィジェットを配置する場所、ウィジェットのサイズ、ウィジェットの位置を指定することができます。
スロットは、ウィジェットをキャンバスに配置するための強力なツールです。スロットを使用することで、ウィジェットをキャンバスの任意の場所やサイズに配置することができます。
エンドゲームの仕掛けを起動
▼ 「countdown_timer_example.verse」で CountdownEndedEvent を待ち、エンド ゲームの仕掛けを起動します。
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
OnBegin<override>()<suspends> : void =
# OnBeginイベントをオーバーライドし、このコードブロックの実行を一時停止します。
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
# AddMoreTimeButtonのInteractedWithEventに対して購読(Subscribe)し、そのイベントが発生した時にOnButtonInteractedWith関数を呼び出します。
if:
# 条件をチェックするためのif文:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
# Playspaceオブジェクトに所属するプレイヤーのリストを取得し、その最初のプレイヤーをFirstPlayer変数に代入します。
PlayerUI := GetPlayerUI[player[FirstPlayer]]
# GetPlayerUI関数を使用して最初のプレイヤーに関連するUIを取得し、変数PlayerUIに代入します。
then:
# もしif文の条件が真(true)の場合、以下のブロックを実行します:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
# countdown_timerクラスのインスタンスを作成し、MaybePlayerUIにPlayerUIをオプションの引数として渡し、RemainingTimeにInitialCountdownTimeを設定します。
CountdownTimer.StartCountdown()
# CountdownTimerインスタンスのカウントダウンを開始します。
CountdownTimer.CountdownEndedEvent.Await()
# CountdownTimerのCountdownEndedEventが発生するまで待機します。
EndGame.Activate(FirstPlayer)
# EndGameを最初のプレイヤーをパラメータとしてアクティブ化します。
else:
# もしif文の条件が偽(false)の場合、以下のブロックを実行します:
Print("Can't find player")
# "Can't find player"というメッセージを出力し、最初のプレイヤーが見つからなかったことを示します。
クリックすると開きます。
このコードは、ゲーム内のカウントダウンタイマーを使用してエンドゲームの仕掛けを起動するシナリオを示しています。
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
このコードは、OnBegin
というイベント(ゲーム内の初期化イベントの一つ)が発生した時に実行される処理を示しています。
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
:AddMoreTimeButton
というボタンのイベントである InteractedWithEvent
を購読し、そのイベントが発生したら OnButtonInteractedWith
という関数を呼び出します。- つまり、ボタンが押されたことを検知して特定の処理を実行するという設定です。
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
:Self.GetPlayspace().GetPlayers()
は、ゲーム内のプレイヤーのリストを取得し、[0]
でその中の最初のプレイヤーを選択しています。FirstPlayer
はそのプレイヤーを指す変数です。
PlayerUI := GetPlayerUI[player[FirstPlayer]]
:GetPlayerUI[player[FirstPlayer]]
で、プレイヤーに関連するUIを取得しています。- これにより、
PlayerUI
にそのUIを格納します。
CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
:countdown_timer
というカウントダウンタイマーのインスタンスを作成し、MaybePlayerUI
に option{PlayerUI}
を、RemainingTime
に InitialCountdownTime
を設定します。- タイマーの初期化が行われます。
CountdownTimer.StartCountdown()
:- カウントダウンタイマーが開始されます。
- 具体的な実装内容はデータモデル
countdown_timer
に依存します。
CountdownTimer.CountdownEndedEvent.Await()
:- カウントダウンタイマーの
CountdownEndedEvent
を待機します。 - このイベントは、タイマーが終了すると発生します。
Await()
はイベントの完了を待機するためのメソッドであり、処理はここで一時停止します。
EndGame.Activate(FirstPlayer)
:EndGame
をアクティブにし、FirstPlayer
をエンドゲームに渡します。- 具体的な実装は不明ですが、おそらくエンドゲームの処理を開始するために使用されるメソッドまたは関数でしょう。
Print("Can't find player")
:- もしプレイヤーが見つからなかった場合に、「Can't find player」というメッセージを表示します。
以上が、プログラムの各行の解説です。
ゲームの初期化時にボタンのイベントを購読し、特定のUI要素を取得してカウントダウンタイマーを開始し、タイマーが終了するのを待ってからエンドゲームを起動するという流れです。
GetPlayerUIの詳細
クリックすると開きます。
GetPlayerUI関数は、Playerに関連付けられたplayer_uiコンポーネントを返す関数です。この関数は、Playerに関連付けられたplayer_uiが存在しない場合には失敗します。
関数のシグネチャ:
GetPlayerUI(Player: player) -> player_ui
パラメータ:
- Player: Player型のパラメータです。これは、player_uiを取得したいプレイヤーオブジェクトです。
戻り値:
- player_ui: player_ui型の戻り値です。関数が成功し、関連付けられたplayer_uiを見つけた場合、そのplayer_uiコンポーネントを返します。
この関数を使用することで、指定したPlayerに関連付けられたプレイヤーUIコンポーネントを取得することができます。
UIコンポーネントは、通常、ゲーム内のプレイヤーのインターフェースや表示に使用されます。
コンポーネントとは
クリックすると開きます。
コンポーネントとは、ゲームオブジェクトに関連付けられた機能を表すオブジェクトです。コンポーネントは、ゲームオブジェクトの見た目、動き、挙動を制御します。
たとえば、ゲームオブジェクトに「移動」コンポーネントを関連付けると、ゲームオブジェクトは移動できるようになります。
ゲームオブジェクトに「攻撃」コンポーネントを関連付けると、ゲームオブジェクトは攻撃できるようになります。
コンポーネントは、ゲームオブジェクトをカスタマイズしたり、ゲームオブジェクトの機能を追加したりするために使用されます。
コンポーネントとメソッドの違い
クリックすると開きます。
コンポーネントとメソッドは、プログラミングにおいて異なる概念を表します。
コンポーネントは、機能や特定の目的を持つ独立した部品や部分です。
コンポーネントは、大きなソフトウェアシステムを機能的に分割し、メンテナンスや再利用性を向上させるために使用されます。
データや処理のまとまりであり、一般的には複数の関連するメソッドやプロパティから構成されます。
例えば、ゲームエンジンの中でUIコンポーネント、音声コンポーネント、物理エンジンコンポーネントなどの異なる機能を持った部品がコンポーネントとなります。
メソッドは、プログラムで実行される具体的な操作や機能を表す関数のことです。
特定のタスクを実行するための手順や処理のまとまりです。
例えば、データの操作や計算、データの表示、他のコンポーネントとのインタラクションなどの機能を持つメソッドがあります。
メソッドは、オブジェクトやクラスに定義され、それらのオブジェクトに対して呼び出すことができます。
コンポーネントとメソッドの関係は、以下のように説明できます。
- コンポーネントは、関連するメソッドやデータをまとめたものです。
- コンポーネントはある特定の機能や目的を持ち、その機能を実現するためのメソッドを提供します。
- 例えば、UIコンポーネントには表示や操作に関連するメソッドが含まれます。
- メソッドは、コンポーネント内に定義された具体的な操作や機能を表します。
- メソッドは特定の処理を実行し、データの変更や計算、他のオブジェクトとのやり取りなどのタスクを実現します。
要約すると、コンポーネントは機能や目的を持った部品であり、メソッドはコンポーネント内で定義された具体的な操作や機能の実装手段です。
コンポーネントは抽象的なまとまりを表し、メソッドは具体的なタスクを実装します。
両者が連携してプログラムの機能を提供し、大規模なソフトウェア開発を支えます。
具体例
コンポーネントとメソッドの違いを、建物(House)とその中の設備(家電製品)に例えて説明します。
コンポーネントは、建物(House)自体を表します。
建物は、居住空間や機能を提供するために設計された大きな構造物です。
建物には複数の部屋やエリアがあり、それぞれが異なる目的や機能を持っています。
例えば、リビングルーム、キッチン、寝室などの部屋は、建物全体の機能をサポートする役割を果たします。
メソッドは、建物(House)内の設備(家電製品)に例えることができます。
設備は、特定の目的で使用される具体的な機器や装置であり、建物の機能を補完します。
例えば、冷蔵庫、テレビ、洗濯機などは、それぞれの機能に特化したメソッドのような存在です。
冷蔵庫は食材を冷やすための機能を持ち、テレビは視聴体験を提供し、洗濯機は衣類の洗濯機能を実行します。
この例を使って具体的に説明すると、建物(コンポーネント)はリビングルームやキッチンといった様々な部屋(メソッド)を含んでいます。
リビングルームにはテレビやソファ、キッチンには冷蔵庫や電子レンジといった設備(メソッド)があります。
それぞれの設備は独自の機能を持ち、その機能を使用することで全体としての建物の機能が向上します。
コンポーネントとメソッドの関係は、建物と設備の関係に似ています。建物(コンポーネント)は、部屋(メソッド)を持ち、それぞれの部屋は独自の機能(メソッドの処理)を提供します。
設備(メソッド)は、部屋内で特定のタスクを実行するための具体的な手段や機器です。
この例を通じて、コンポーネントとメソッドの違いをより具体的にイメージしやすくなったかと思います。

あすか
PlayerUI := GetPlayerUI[player[FirstPlayer]]の記述理由
クリックすると開きます。
「PlayerUI := GetPlayerUI[player[FirstPlayer]]」の部分は、最初のプレイヤーに関連付けられたUIを取得するために記述されています。このコードによって、最初のプレイヤーのUIを取得し、変数 PlayerUI
に保存することができます。
このような操作が必要な理由は、おそらく以下の処理で使用されるためです。
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
上記のコードでは、CountdownTimer
というオブジェクトを作成しています。
これには MaybePlayerUI
というパラメータがあり、それには PlayerUI
の値が渡されています。
このように、プレイヤーのUIをカウントダウンタイマーに関連付けることで、UIに関連するタイマーイベントなどを実行することができます。
したがって、「PlayerUI := GetPlayerUI[player[FirstPlayer]]」のコードは、最初のプレイヤーに関連付けられたUIを取得して利用するために必要です。
ただし、前提条件として、GetPlayerUI
が正しく動作し、適切な引数で呼び出される必要があります。
UIを記述しなかった場合に想定される問題
「PlayerUI := GetPlayerUI[player[FirstPlayer]]」のコードが最初のプレイヤーに関連付けられたUIを取得できなかった場合、次のような問題が生じる可能性があります:
CountdownTimer
の作成時にエラーが発生する可能性があります。PlayerUI
の値がnil
または無効な値の場合、CountdownTimer
の生成時にエラーが発生し、プログラムの実行が中断される可能性があります。
- カウントダウンタイマーに関連するUIイベントが機能しない場合があります。
- もし
PlayerUI
が無効な値ならば、カウントダウンタイマーがUI上で正しく動作しない可能性があります。 - 例えば、タイムアップのイベントが表示されない、UI上のタイマーバーが表示されないなどの問題が発生するかもしれません。
- ゲーム終了処理が不完全になる可能性があります。
EndGame.Activate(FirstPlayer)
を呼び出す際に、正しいプレイヤーが見つからない場合、ゲーム終了処理が適切に実行されないことがあります。
その他の具体的な問題や影響は、ゲームのロジックやコードの他の部分に依存することがあります。応答的なUIイベントやプレイヤーに関連する処理がある場合は、それらの処理に影響を与える可能性があります。
したがって、最初のプレイヤーに関連付けられたUIを正常に取得することが重要であり、取得できない場合には適切なエラーハンドリングや代替処理を実装する必要があります。
PlayerUI := GetPlayerUI[player[FirstPlayer]]の記述理由
クリックすると開きます。
PlayerUI := GetPlayerUI[player[FirstPlayer]]
は、与えられたプレイヤーに関連付けられたプレーヤーのUI(ユーザーインターフェース)を取得するためのコードです。
この行の解説をさらに詳しく説明します。
Self.GetPlayspace().GetPlayers()
は、現在のプレイスペース内のすべてのプレイヤーを取得するためのコードです。- このリストから最初のプレイヤーを選ぶために
[0]
が使われています。
player[FirstPlayer]
は、選択された最初のプレイヤーを使用して、player
という辞書またはリスト(データ構造)から関連する値を取得するための記法です。- この場合、
player
はプレイヤーごとに対応する値(おそらくそれぞれのプレイヤーに対応するUI)を保持していると推測されます。
GetPlayerUI[...]
は、与えられたプレイヤーに関連付けられたUIを取得するための関数または辞書の要素へのアクセスです。- 具体的には、
...
の部分は player[FirstPlayer]
から取得した値(おそらくUI)です。
PlayerUI := ...
は、PlayerUI
という変数に GetPlayerUI[...]
から返された結果(おそらくプレーヤーのUI)を代入するためのコードです。
したがって、この行の目的は、最初のプレイヤーに関連付けられたUIを取得し、そのUIを変数 PlayerUI
に保存することです。
これにより、後続のコードでそのUIを使用することができます。ただし、条件式 if
がない場合、エラーが発生する可能性があるため、注意が必要です。
FirstPlayerキーが取得する値
クリックすると開きます。
FirstPlayer
は Self.GetPlayspace().GetPlayers()[0]
の結果として設定される値です。
Self.GetPlayspace().GetPlayers()
は、現在のプレイスペース内のすべてのプレイヤーを返すリストまたは配列です。
そして [0]
はリストの最初の要素を表します。
つまり、FirstPlayer
は現在のプレイスペース内の最初のプレイヤーを指します。これは一般的にはリスト内の0番目の要素に相当しますが、実際の値は実行時に決まります。
具体的なプレイヤーの値は、実行環境やゲームのロジックに依存します。例えば、プレイヤーはユーザーごとに識別される一意の識別子(ID)を持つかもしれません。その場合、FirstPlayer
は最初のプレイヤーのIDを表すことになります。
実行時に FirstPlayer
の値がどのように設定されるかは、コードを実行する環境と具体的なゲームのロジックによって異なります。そのため、具体的な値については提供されたコードからは判断できません。
具体的に
FirstPlayer
はおそらく「最初のプレイヤー」を表す変数であり、その値は実行時に動的に設定される可能性があります。
一般的なゲームの場合、FirstPlayer
の値は通常、プレイヤーを特定する一意の識別子(ID)や参加順などに関連付けられます。たとえば、プレイヤーIDやプレイヤーのオブジェクトなどが候補となります。
そのため、FirstPlayer
の実際の値はゲームのコンテキストやゲームエンジンなどの詳細に依存します。
コードを実際に実行する際に、初期のプレイヤーがどのように決定されるかを確認する必要があります。
条件式の記述理由
クリックすると開きます。
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
この条件式は、最初のプレイヤーを確認しています。これはゲーム内の特定のアクションや処理を実行するために、最初のプレイヤーの存在を確認する必要があるからです。
以下に解説を詳しく記載しました。
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
: Self
オブジェクトが属しているプレイスペースから、プレイヤーのリストを取得し、そのリストの最初の要素 [0]
を FirstPlayer
という変数に代入します。- この行の目的は、最初のプレイヤーを特定することです。
PlayerUI := GetPlayerUI[player[FirstPlayer]]
: GetPlayerUI
という関数を使用して、プレイヤーの UI(ユーザーインターフェース)を取得し、PlayerUI
という変数に代入しています。- ただし、
player
という配列または連想配列(辞書)が事前に定義されている必要があります。
if
文の条件部分: - もし上記のプレイヤーと UI の取得が成功した場合、つまり
FirstPlayer
と PlayerUI
の両方が存在する場合は、以下の処理を実行します。
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
: countdown_timer
というカウントダウンタイマーを作成し、CountdownTimer
という変数に代入します。- このとき、
MaybePlayerUI
というオプション(もしくはnullable)のパラメータに PlayerUI
を渡し、RemainingTime
には InitialCountdownTime
という初期値を設定しています。
CountdownTimer.StartCountdown()
: カウントダウンを開始します。CountdownTimer.CountdownEndedEvent.Await()
: カウントダウンが終了するのを待ちます。EndGame.Activate(FirstPlayer)
: - ゲームの終了処理を行います。
EndGame
オブジェクトの Activate
メソッドを呼び出し、引数として最初のプレイヤー FirstPlayer
を渡します。
else
文の場合: - もし最初のプレイヤーと UI の取得が失敗した場合(存在しない)、
Can't find player
というメッセージを出力します。
したがって、この条件式を使用することで、最初のプレイヤーが存在し、関連する UI も取得できる場合は特定の処理を実行し、存在しない場合はエラーメッセージを出力することができます。
条件式を使わないと生じる問題
もし条件式を使わずにこのコードを実行した場合、以下のような問題が生じる可能性があります:
- エラー:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
の部分で、プレイスペースからプレイヤーリストを取得する際に、プレイヤーが存在しない場合にインデックスエラーが発生する可能性があります。- このエラーはプレイヤーリストが空の場合に最初の要素
[0]
をアクセスしようとしたときに発生します。
- ヌルポインタ例外:
PlayerUI := GetPlayerUI[player[FirstPlayer]]
の部分で、プレイヤーの UI を取得しようとする際に、最初のプレイヤーが存在しない場合、もしくは関連する UI が見つからない場合にエラーが発生する可能性があります。- これにより、後続の処理でヌルポインタ例外が発生する可能性があります。
- ロジックエラー:
CountdownTimer
という変数が初期化されずに使用されるため、カウントダウンタイマーの作成と開始が行われず、後続の CountdownTimer.StartCountdown()
や CountdownTimer.CountdownEndedEvent.Await()
に関連する処理は実行されません。
- ゲームの終了処理がスキップされる:
EndGame.Activate(FirstPlayer)
の部分が実行されず、ゲームの終了処理がスキップされます。- このため、ゲームの状態が正しく管理されず、不測の問題が発生する可能性があります。
- 適切なエラーメッセージの欠如:
- 条件が満たされない場合に、プレイヤーが見つからなかったことを示すメッセージが出力されないため、デバッグやトラブルシューティングの際に問題の特定が困難になる可能性があります。
したがって、条件式がない場合、不正な状態によるエラーや予期しない振る舞いが生じる可能性があります。
条件式を使用することで、正しいプレイヤーと関連する UI の存在を確認し、適切な処理フローを実行することができます。
Selfの詳細
クリックすると開きます。
Self
は、オブジェクト自体を指すキーワードです。このコード内では、Self
がメソッド OnBegin
の実行元のオブジェクトを参照しています。
通常、オブジェクト指向プログラミングでは、クラスや構造体を定義し、それを基に複数のインスタンス(オブジェクト)を生成します。
それぞれのインスタンスは、クラスまたは構造体の定義に基づき、独自の状態(データ)とメソッド(関数)を持ちます。
Self
を使用することで、メソッド内部でそのオブジェクト自体にアクセスできます。例えば、Self.GetPlayspace()
は、Self
オブジェクトの GetPlayspace()
メソッドを呼び出し、関連するプレイスペースを取得することを意味します。
具体的には、Self.GetPlayspace().GetPlayers()[0]
の部分では、Self
オブジェクトの GetPlayspace()
メソッドを呼び出し、プレイスペースを取得しています。
その後、取得したプレイスペースの GetPlayers()
メソッドを呼び出し、プレイヤーのリストを取得しています。
最後に、そのリストの最初の要素 [0]
を選択しています。
つまり、Self.GetPlayspace().GetPlayers()[0]
の部分は、Self
オブジェクトが属しているプレイスペースから最初のプレイヤーを取得するためのコードです。
このようにして Self
キーワードを使用することで、オブジェクト内のメソッドやデータにアクセスできます。
if FirstPlayer := S~の詳細
クリックすると開きます。
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
if
ブロックは、条件が真(true)の場合に実行されるコードブロックです。
このコードでは、最初のプレイヤー(FirstPlayer
)とそのプレイヤーに関連するUI(PlayerUI
)を取得するためのコードが if
ブロック内にあります。
まず、Self.GetPlayspace().GetPlayers()[0]
は、現在のオブジェクト(Self
)が所属しているプレイスペース(Playspace)からプレイヤーのリストを取得し、その中の最初のプレイヤーを選択しています。
この部分では、プレイヤーがリスト内でどの位置にあるかに基づいて最初のプレイヤーを選択していることに注意してください。
次に、GetPlayerUI[player[FirstPlayer]]
の部分では、GetPlayerUI
関数を使用して最初のプレイヤー(FirstPlayer
)に関連するUIを取得しています。
ここで player[FirstPlayer]
は、player
という配列(または辞書)の FirstPlayer
番目の要素を取得するという意味です。
具体的には、プレイヤーに関連するUIを取得するためのキーを指定しています。
したがって、FirstPlayer
にはプレイヤーが、PlayerUI
にはそのプレイヤーに関連するUIが代入されます。
if
ブロック内のこのコードセグメントは、最初のプレイヤーとそのプレイヤーに関連するUIを取得するために使用されます。
条件が真(true)であれば、その後のコードブロックが実行されます。
条件が偽(false)であれば、else
ブロックの中にある Print
文が実行され、"Can't find player" というメッセージが表示されます。
オブジェクトを具体的に
オブジェクトは、具体的には「ゲームのキャラクター」です。
Self.GetPlayspace()
メソッドは、ゲームのキャラクターが属しているプレイスペースを取得します。
Self.GetPlayspace().GetPlayers()
メソッドは、プレイスペースに存在するプレイヤーのリストを取得します。
Self.GetPlayspace().GetPlayers()[0]
は、プレイスペースに存在するプレイヤーのリストの最初の要素を取得します。
つまり、Self.GetPlayspace().GetPlayers()[0]
は、ゲームのキャラクターが属しているプレイスペースに存在する最初のプレイヤーを取得するためのコードです。
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)の詳細
クリックすると開きます。
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
は、イベントの購読(Subscribe)を行うコードです。
イベントは、特定のアクション(ボタンのクリック、マウスの移動など)が発生したときに通知を受ける仕組みです。
このコードでは、AddMoreTimeButton
の InteractedWithEvent
イベントに対して購読(Subscribe)を行っています。
つまり、AddMoreTimeButton
というオブジェクトでボタンがクリックされたときに、指定した処理を実行するように設定しています。
具体的には、このコードでは OnButtonInteractedWith
という関数(またはメソッド)が定義されていることを前提としています。
購読(Subscribe)によって、AddMoreTimeButton
の InteractedWithEvent
イベントが発生したときに、OnButtonInteractedWith
関数が呼び出されるようになります。
その際には、イベントが発生したときの詳細な情報やイベントの引数を関数に渡すことができます。
たとえば、あるボタンがクリックされたら画面上にメッセージを表示したい場合、OnButtonInteractedWith
関数の中にメッセージを表示するコードを記述します。
そして、AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
のコードを実行することで、イベントの購読が開始され、ボタンがクリックされたときに関数が呼び出され、メッセージが表示されるようになります。
このようにイベントの購読は、ユーザーのアクションやシステム上の重要な変化に対して反応するための重要な仕組みです。
オーバーライドとは
クリックすると開きます。
オーバーライドとは、親クラスから継承したメソッドを子クラスで再定義することです。
オーバーライドされたメソッドは、親クラスのメソッドと同じ名前、同じ引数、同じ戻り値型を持つ必要があります。
オーバーライドされたメソッドは、親クラスのメソッドと同じ動作をしますが、子クラスの固有の処理を追加することもできます。
たとえば、親クラスのメソッドでデータベースからデータを取得する処理を行っている場合は、子クラスのメソッドでデータを加工する処理を追加することができます。
オーバーライドを使用すると、親クラスのメソッドを拡張したり、変更したりすることができます。これにより、コードの再利用性を高めることができます。
計算式の論理
クリックすると開きます。
このコードは、「OnBegin」というイベントが発生したときに実行される処理を表しています。以下に、各計算式の論理を分かりやすく解説します。
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
- 意味:
AddMoreTimeButton
の InteractedWithEvent
というイベントが発生したときに、OnButtonInteractedWith
という関数を実行する。 - 解説:
AddMoreTimeButton
はボタンのオブジェクトを表し、そのボタンが押されたときに何かの処理を行いたい場合に使用します。この行のコードでは、ボタンが押されたことを検知するために、InteractedWithEvent
イベントを購読し、イベント発生時に OnButtonInteractedWith
関数が呼び出されるように設定されています。
if: FirstPlayer := Self.GetPlayspace().GetPlayers()[0]; PlayerUI := GetPlayerUI[player[FirstPlayer]]
- 意味: もし、最初のプレイヤーが存在し、そのプレイヤーに関連するUIがある場合に以下の処理を実行する。
- 解説: この行では、条件文を使用して特定の条件を満たした場合に処理を実行するかを判断しています。まず、
Self.GetPlayspace().GetPlayers()
を使用してプレイヤーのリストを取得し、[0]
を使って最初のプレイヤーを選択します。そのプレイヤー変数を FirstPlayer
に割り当てます。さらに、GetPlayerUI[player[FirstPlayer]]
を使って、最初のプレイヤーに関連するUIを取得し、PlayerUI
に割り当てます。
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
- 意味: カウントダウンタイマーのインスタンスを作成し、プレイヤーのUIと初期残り時間を設定する。
- 解説: この行では、
countdown_timer
のインスタンスを作成します。MaybePlayerUI
というパラメータには、option{PlayerUI}
というUIを持つ可能性があります。RemainingTime
では、InitialCountdownTime
という変数に格納されている初期の残り時間を設定します。
CountdownTimer.StartCountdown()
- 意味: カウントダウンタイマーを開始する。
- 解説:
CountdownTimer
のインスタンスに対して、StartCountdown()
というメソッドを呼び出してカウントダウンを開始します。
CountdownTimer.CountdownEndedEvent.Await()
- 意味: カウントダウンタイマーの終了まで待機する。
- 解説:
CountdownTimer
の CountdownEndedEvent
イベントが発生するまで、処理を一時停止します。つまり、タイマーのカウントダウンが終了するのを待ちます。
EndGame.Activate(FirstPlayer)
- 意味: エンドゲームをアクティブにし、最初のプレイヤーを渡す。
- 解説:
EndGame
というオブジェクトやコンポーネントをアクティブにし、最初のプレイヤーを渡してエンドゲームの処理を開始します。
Print("Can't find player")
- 意味: プレイヤーが見つからなかった場合に、"Can't find player" というメッセージを表示する。
- 解説: もし
if
の条件が満たされなかった場合、つまり最初のプレイヤーが存在しなかった場合にこの行のコードが実行され、"Can't find player" というメッセージが表示されます。
以上が各計算式の論理の解説です。このコードの目的は、ゲームの初期化時に特定の条件を満たした場合にカウントダウンタイマーを開始し、タイマーの終了後にエンドゲームの処理を行うことです。また、プレイヤーやUIといったゲームの要素を操作していることがわかります。
GetPlayerUI[player[FirstPlayer]]のplayerはなくてもいい?
クリックすると開きます。
いいえ、GetPlayerUI[player[FirstPlayer]]
を[FirstPlayer]
と単に書くことは機能しません。
player[FirstPlayer]
は配列player
にインデックスでアクセスして要素を取得しているため、[FirstPlayer]
という単体の表記では意図した結果を得ることはできません。
player[FirstPlayer]
は、FirstPlayer
で示される要素のインデックスにアクセスして配列player
の要素を取得するために使用されています。
例えば、FirstPlayer
が1であった場合、player[FirstPlayer]
はplayer[1]
となり、配列player
の1番目の要素を取得します。
player
がプレイヤーのコレクションを表す配列であり、その要素はプレイヤーオブジェクトやプレイヤーIDなど何らかの値が格納されていることを想定しています。
したがって、GetPlayerUI[player[FirstPlayer]]
のように正確なインデックス指定が必要です。
[FirstPlayer]
だけでは意図した要素を正確に参照することはできません。
「player」と記述する理由
GetPlayerUI
関数は、与えられたPlayer
に関連付けられたplayer_ui
コンポーネントを返す関数です。関連するplayer_ui
が存在しない場合、この関数は失敗します。
以下に、GetPlayerUI
関数の詳細を解説します。
- 関数の型:
player_ui
- 公開されている (
public
) ネイティブ (UEBNative) 関数
パラメータ:
Player
: player
型Player
は、player
型の引数です。これは特定のプレイヤーを指定します。
戻り値:
player_ui
: player_ui
型GetPlayerUI
関数は、関連付けられたplayer_ui
コンポーネントを返します。
この関数は、与えられたプレイヤー(Player
)に関連付けられたplayer_ui
コンポーネントを取得するために使用されます。
player_ui
コンポーネントは、通常、プレイヤーのインターフェース (UI) 表示を制御するために使用されます。
プレイヤーのスコアやヘルスバー、アバターの表示など、プレイヤーに関連した情報や要素を表示するために利用されることがあります。
この関数を使用する際には、有効なPlayer
が必要です。Player
に関連付けられたplayer_ui
が存在しない場合、関数は失敗します。
この場合、関連付けられたplayer_ui
を見つけるために別の手段が必要になる可能性があります。
以上が、GetPlayerUI
関数に関する解説です。この関数を呼び出すことで、特定のプレイヤーに関連付けられたplayer_ui
コンポーネントを取得することができます。
FirstPlayerとPlayerUIの格納内容の違い
クリックすると開きます。
FirstPlayer
とPlayerUI
は、異なる種類の情報を格納しています。
FirstPlayer
: FirstPlayer
は、Self.GetPlayspace().GetPlayers()
から取得されるプレイヤーコレクションの最初のプレイヤーを表す変数です。GetPlayers()
はプレイスペース内のすべてのプレイヤーを取得し、その中から最初のプレイヤーを選択します。FirstPlayer
は特定のプレイヤーを示すオブジェクトやIDなどの情報を保持していると想定されます。
PlayerUI
: PlayerUI
は、GetPlayerUI[player[FirstPlayer]]
から取得されるプレイヤーに関連付けられたUIコンポーネントを示す変数です。GetPlayerUI
関数は、プレイヤーに関連付けられたplayer_ui
コンポーネントを取得するために使用されます。PlayerUI
は、具体的なUIコンポーネントやその参照を格納していることを想定しています。
したがって、FirstPlayer
はプレイヤー自体を示し、PlayerUI
はそのプレイヤーに関連付けられたUIコンポーネントを示しています。
FirstPlayer
を使用して特定のプレイヤーを識別し、そのプレイヤーに関連付けられたUIコンポーネントをPlayerUI
に格納し、それを後続の処理で使用することができます。
UIコンポーネントとは
UIコンポーネントは、ユーザーインターフェース (UI) の一部として機能する要素です。ゲームやアプリケーションのUIは、プレイヤーやユーザーに情報を表示し、対話や操作を可能にするために使用されます。
UIコンポーネントは、表示されるテキスト、ボタン、イメージ、スライダーなど、さまざまな種類の要素で構成されることがあります。
UIコンポーネントは、プレイヤーやユーザーとのインタラクションを処理するためのイベントやアクションも提供します。ユーザーがボタンをクリックしたり、テキストフィールドに入力したり、スライダーを動かしたりすると、UIコンポーネントはそれに応じて動作します。例えば、ボタンのクリックに応じてゲーム内のアクションをトリガーしたり、テキストフィールドの内容を処理したりすることができます。
UIコンポーネントは通常、ゲームエンジンやアプリケーションフレームワークに組み込まれており、それぞれ固有の方法で操作やスタイル設定が可能です。開発者はUIコンポーネントを配置し、表示内容や振る舞いを設定することで、ユーザーフレンドリーなインターフェースを作成することができます。
最も一般的なUIコンポーネントには、テキスト表示用のラベル、ボタン、チェックボックス、ドロップダウンリスト、スライダー、テキストボックスなどがあります。これらのコンポーネントは、ユーザーがゲームやアプリケーションと対話するために重要な役割を果たします。
UIコンポーネントは、ユーザーに情報を提供したり、ユーザーの入力や操作を処理したりするため、直感的で使いやすいデザインが求められます。開発者は、UIコンポーネントの配置、スタイル、インタラクションの設定などを慎重に行い、ユーザーが快適に利用できるUIを作り上げることが重要です。
プレイヤーの情報を保持するのか
UIコンポーネント自体は通常、プレイヤーの情報を直接的には保持しません。
UIコンポーネントは、その表示や操作に関連するデータや動作を管理するための仕組みです。
しかし、UIコンポーネントはしばしばプレイヤーの情報を表示したり、その情報に基づいて動作したりするために使用されます。
例えば、プレイヤーの名前やアバターの画像を表示するラベルやイメージコンポーネント、プレイヤーのスコアや進行状況を表示するテキストフィールド、プレイヤーの選択肢や操作ボタンを提供するボタンなどが一般的なUIコンポーネントの例です。
プレイヤーの情報は通常、ゲームエンジンやアプリケーションのデータ構造や変数に格納されます。UIコンポーネントは、これらのプレイヤー情報へのアクセス方法を提供し、適切な時点で情報を取得して表示する役割を果たします。
具体的には、ゲームやアプリケーションのロジックからプレイヤーの情報を取得し、それをUIコンポーネントに反映させるか、逆にUIコンポーネントからのユーザーの操作を受け取り、それをプレイヤーのデータやゲームの状態の更新に反映させることが一般的です。
つまり、UIコンポーネントはプレイヤーの情報を表示したり、プレイヤーとの対話を実現したりするための仕組みであり、プレイヤーの情報自体は別の場所に格納されます。
つまり、管理局だ。
はい、そのように言えます。UIコンポーネントは、プレイヤーの情報にアクセスして、その情報を適切に表示したり、ユーザーの操作に応じて情報を更新したりする管理役割を果たします。
UIコンポーネントは、ゲームやアプリケーションの他の部分と連携し、プレイヤーやユーザーとの対話を仲介する役割を果たします。
UIコンポーネントは、ゲームエンジンやアプリケーションフレームワークと連携して、プレイヤーの情報を取得し、それを画面上に表示します。また、ユーザーの操作を検知し、適切なアクションやイベントを起動することで、プレイヤーのデータを更新することもあります。
このような仕組みにより、UIコンポーネントはプレイヤーとゲームやアプリケーションの間の情報のやり取りを取り扱い、ユーザーエクスペリエンスを向上させるのに役立ちます。プレイヤーがゲームやアプリケーションと対話する際、UIコンポーネントはプレイヤー情報の表示や操作を容易にし、よりスムーズなプレイ体験を提供します。
管理内容
PlayerUIに含まれる情報は、具体的なゲームやアプリケーションの設計や要件によって異なります。しかし、一般的にPlayerUIは以下のような情報を管理することがあります。
- プレイヤーの名前: プレイヤーのユーザー名や表示名を管理し、表示するための情報です。
- プレイヤーのスコア: ゲームやアプリケーション内でのプレイヤーの得点や進行状況を表示するための情報です。
- プレイヤーのアバター: プレイヤーのキャラクターやアバターの画像や表示情報を管理することがあります。
- プレイヤーのライフや体力: ゲーム内でのプレイヤーの残機や体力を管理し、UI上で表示することがあります。
- プレイヤーのアイテムや装備: ゲーム内でのプレイヤーが所持しているアイテムや装備品の情報を管理し、UI上で表示することがあります。
- プレイヤーの通知やメッセージ: ゲームやアプリケーションからプレイヤーに伝えるべきメッセージや通知情報を管理し、UI上で表示することがあります。
これらは一般的な例であり、具体的な要件によって異なる場合もあります。ゲームやアプリケーションの設計や目的に基づいて、PlayerUIは必要な情報を管理して表示する役割を果たします。
then:~EndGame.Activateまでの詳細
クリックすると開きます。
下記のコードブロックは、あるイベントが発生した時に実行される処理を表しています。
以下に解説を行います。
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
まず、CountdownTimer
という変数を作成します。この変数はcountdown_timer
というクラスのインスタンスを表しています。
countdown_timer
はカウントダウン機能を持つタイマーを制御するためのクラスです。
CountdownTimer
の作成時には、MaybePlayerUI
とRemainingTime
というパラメータが指定されています。
MaybePlayerUI := option{PlayerUI}
の部分では、PlayerUI
をoption
というデータ型のオブジェクトにラップすることで、PlayerUI
をCountdownTimer
に渡すことができます。
これにより、タイマーがUIと関連付けられ、UI上で表示されることが可能になります。
次に、CountdownTimer.StartCountdown()
を呼び出すことで、カウントダウンが開始されます。カウントダウンは指定した時間(InitialCountdownTime
)から0まで進みます。
その後、CountdownTimer.CountdownEndedEvent.Await()
が呼び出されます。この行は、カウントダウンが終了するまでプログラムの実行を一時停止(スリープ)させます。つまり、この行の下の処理は、カウントダウンが終了した後に再開されることになります。
最後に、EndGame.Activate(FirstPlayer)
が呼び出されます。この行は、ゲームを終了させるための処理を行います。FirstPlayer
は最初のプレイヤーを表す変数であり、EndGame.Activate()
によって、そのプレイヤーを使用してゲームを終了する処理が実行されます。
以上が、上記のコードブロックの解説です。
このコードは、イベントが発生した時に指定のプレイヤーのUI上にカウントダウンタイマーを表示し、カウントダウンが終了した後にゲームを終了するという処理を行うものです。
計算式の論理
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
このコードは次の手順で処理を行います。
CountdownTimer
という変数を作成し、countdown_timer
というクラスのインスタンスを代入します。- これにより、
CountdownTimer
はcountdown_timer
クラスのインスタンスを参照することができるようになります。
CountdownTimer
の作成時には、2つの情報が与えられます。
PlayerUI
をMaybePlayerUI
という名前のオプション(値の存在を示すオブジェクト)に格納します。これにより、PlayerUI
の値をCountdownTimer
内で使用することができます。InitialCountdownTime
をRemainingTime
という名前の変数に格納してカウントダウンの初期残り時間を設定します。
CountdownTimer.StartCountdown()
を呼び出すことで、カウントダウンが開始されます。これにより、指定された時間から始まり、時間が減少していきます。CountdownTimer.CountdownEndedEvent.Await()
は、カウントダウンが終了するまでプログラムの実行を一時停止(待機)させます。つまり、この行の次の処理は、カウントダウンが終了するまで実行されません。- カウントダウンが終了した後、
EndGame.Activate(FirstPlayer)
が呼び出されます。この行は、EndGame
オブジェクトのActivate()
メソッドを使用して、指定されたFirstPlayer
をゲームの終了処理に渡します。
したがって、上記のコードの目的は、PlayerUI
を使用してカウントダウンタイマーを表示し、カウントダウンが終了した後に指定されたプレイヤーを使用してゲームを終了することです。
引数は関数以外でも使用する
クリックすると開きます。
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
引数は関数の実行時に渡される値を指すものだけでなく、オブジェクトのコンストラクタ(初期化子)の場合にも使用されます。
クラスのコンストラクタは、オブジェクトのインスタンス化(作成)時に実行される特殊なメソッドであり、オブジェクトの初期化を担当します。
コンストラクタは通常、クラスのフィールドに初期値を設定するために使用されます。
上記のコードでは、countdown_timer
クラスのコンストラクタが2つの引数、つまりMaybePlayerUI
とRemainingTime
を受け取っています。
これらの引数は、インスタンス化されるcountdown_timer
オブジェクトの初期値を指定するために使用されます。
したがって、正確な表現としては、MaybePlayerUI
とRemainingTime
はcountdown_timer
クラスのコンストラクタの引数です。
これらの引数を使用して、新しいcountdown_timer
オブジェクトが作成されます。
オブジェクトの初期化を意味する?
はい、正確に言えば、クラスのコンストラクタはオブジェクトを初期化するための特殊なメソッドです。コンストラクタはクラスのインスタンス化(オブジェクトの作成)時に呼び出され、そのオブジェクトの初期化を行います。
コンストラクタは、オブジェクトが作成される際に実行されるため、オブジェクトの状態を初期化するための役割を果たします。この初期化には、フィールドの値の初期化や他の必要な処理が含まれる場合があります。
クラスのコンストラクタは通常、new
キーワードを使って呼び出されます。例えば、countdown_timer
クラスのコンストラクタを使用してオブジェクトを作成する場合、次のような形になります:
var myTimer = new countdown_timer(MaybePlayerUI, RemainingTime);
上記の例では、countdown_timer
クラスのコンストラクタにMaybePlayerUI
とRemainingTime
を渡しています。コンストラクタはこれらの引数を受け取り、オブジェクトの初期化を行います。
つまり、クラスのコンストラクタはオブジェクトを初期化させる役割を持っており、オブジェクトを使用する前に適切な状態に設定するための重要なメソッドです。
オブジェクトを初期化させるメリット
オブジェクトを初期化することにはいくつかのメリットがあります。
- オブジェクトの状態の整合性を確保する:
- コンストラクタは、オブジェクトの状態を適切な初期値で設定する役割を果たします。
- これにより、オブジェクトが適切に動作し、意図した通りに利用できるようになります。
- また、初期化されていないオブジェクトを使用することによる不正な操作やエラーを防ぐことができます。
- 必要なリソースの割り当てと解放:
- コンストラクタは、必要なリソース(メモリ、ファイルハンドルなど)を割り当てる際に使用することができます。
- また、オブジェクトが不要になった時には、デストラクタや適切な解放メソッドを使用してリソースを解放することができます。
- これにより、リソースリークやメモリの浪費を防ぐことができます。
- インターフェースの一貫性と利便性:
- コンストラクタを使用してオブジェクトを初期化することで、開発者がオブジェクトの使用方法や必要なパラメータを明示的に指定することができます。
- これにより、オブジェクトの利用方法やメンバーの概要を把握しやすくなり、コードの可読性と保守性が向上します。
- また、コンストラクタを適切に設計することで、オブジェクトの作成や初期化を簡素化し、利用者にとっての利便性が向上します。
- 継承やポリモーフィズムの管理:
- オブジェクトの初期化処理は継承やポリモーフィズムにおいて重要な役割を果たします。
- コンストラクタを使用して派生クラスのインスタンス化と初期化を行うことで、継承関係を適切に管理し、ポリモーフィズムに基づいたオブジェクトの振る舞いを実現することができます。
これらのメリットにより、オブジェクトの初期化はプログラムの正常な動作と保守性の向上に重要な役割を果たします。
コンストラクタの由来
クリックすると開きます。
「コンストラクタ」の用語は、英語の "constructor" に由来しています。"constructor" は、英語の "construct"(構築する、組み立てる)と "or"(または)を組み合わせた言葉です。
この用語は、プログラミングにおいてオブジェクトの構築と初期化を行うための特殊なメソッドを指すことから派生しています。つまり、コンストラクタはオブジェクトのインスタンス化時に呼び出され、そのオブジェクトの構築と初期化を行います。
コンストラクタはクラスの一部であり、オブジェクトのメモリ空間の割り当てや必要な初期化処理を行うために重要な役割を果たしています。そのため、この特殊なメソッドがオブジェクトの構築(construct)に関連するとして「コンストラクタ」という名前が付けられました。
なお、コンストラクタという用語は、オブジェクト指向プログラミングの文脈で一般的に使用されていますが、プログラミング言語や文化によっては、異なる呼称や用語が使われる場合もあります。
コンストラクタの例
クリックすると開きます。
身近なものに例えると、建物の建設に当てはまります。
建物を建てる際には、まず建築設計図があります。この設計図は、建物の構造や特性を定義し、建設工事の指針となります。それに基づいて、実際の建設作業が進められます。
ここで、建築設計図がクラスであり、建物そのものがオブジェクトと言えます。そして、建物を実際に建てるためには、建設工事を行う必要があります。この建設工事の担当者が、コンストラクタです。
コンストラクタは建設工事の一環として、建物のフレームワークや構造を作り上げます。つまり、必要な材料を調達し、基礎を築き、壁や屋根を設置して、完成した建物を初期化する役割を果たします。
コンストラクタは、建物を適切な初期状態で完成させるために必要な処理を行うという点で、建築工事と共通しています。建物が完成した後は、その建物に対して利用者が入居し、さまざまな活動を行うことができます。同様に、オブジェクトのコンストラクタが呼び出されることで、初期化されたオブジェクトが利用可能になり、プログラムでの処理や操作が行われます。
このように、コンストラクタは建物の建設と類似の役割を果たし、オブジェクト指向プログラミングにおいて重要なメソッドとして使用されます。
コンストラクタがない場合に想定される問題
クリックすると開きます。
想定される問題は以下のとおり。
- オブジェクトの初期化:
- コンストラクタはオブジェクトを作成する際に呼び出され、オブジェクトのメンバ変数やその他の状態の初期化を行います。
- これにより、オブジェクトを利用する前に必要な初期化作業を自動的に行うことができます。
- 安全なオブジェクトの生成:
- コンストラクタはオブジェクトの生成と同時に、不正な状態を防止するためのチェックや制約を実施することができます。
- 例えば、特定の条件を満たさない場合にはオブジェクトの生成を中止する、あるいはデフォルト値を設定するなど、必要なバリデーションやエラーハンドリングを行えます。
- オブジェクトの再利用性とシンプルな利用:
- コンストラクタはオブジェクトの生成手順をカプセル化し、繰り返し利用できるコードの塊として提供します。
- これにより、同じクラスの異なるインスタンスを容易に生成することができます。
- 継承やポリモーフィズムのサポート:
- コンストラクタはクラスの継承やポリモーフィズムの仕組みと連携して動作します。
- 派生クラスのコンストラクタは基底クラスのコンストラクタを呼び出し、必要な初期化や処理を実行します。
- これにより、継承関係や階層構造を持つクラスのオブジェクトを適切に初期化することができます。
コンストラクタの利用は、オブジェクト指向プログラミングにおいて重要な概念であり、安全かつ効果的なオブジェクトの生成と初期化を実現するための手段です。
MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTimeの詳細
クリックすると開きます。
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
「MaybePlayerUIに設定値PlayerUIを選択したオプションと、RemainingTimeに初期カウントダウン時間(InitialCountdownTime)を指定したオプションを設定します。」
このコードは、Goや類似のプログラミング言語で使用される構造体や関数などの定義方法に似ています。以下に簡単な解説を行います。
{PlayerUI}
: - これはオプションとして指定される値で、PlayerUIという名前のオプションを表しています。
- オプションは、特定の機能や設定をパラメータとして渡すために使用されます。
:=
: - これは、変数に値を代入するために使用される代入演算子です。
- 「MaybePlayerUI」および「RemainingTime」は変数の名前です。
InitialCountdownTime
: - これは「初期カウントダウン時間」という変数や定数を表しています。
- 具体的な数値や時間の値が代入されることを想定しています。
したがって、上記のコードは、オプションとしてPlayerUIを指定したMaybePlayerUIという変数に対して、RemainingTimeという変数に初期カウントダウン時間の値を指定したオプションを設定するという意味です。
なお、このコードの具体的な動作や目的については、提供された情報が少ないため特定することはできません。
ただし、多くのプログラムでは、オプションや設定を使用して動作や見た目をカスタマイズすることがあります。
計算式
countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
:
countdown_timer
は、おそらく「カウントダウンタイマー」という機能を持つオブジェクトやクラスのインスタンスを作成するためのコードです。{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
は、countdown_timerオブジェクトの初期化パラメータとして、MaybePlayerUIとRemainingTimeを指定しています。MaybePlayerUI := option{PlayerUI}
は、PlayerUIを値とするMaybePlayerUIという名前のオプションを設定しています。RemainingTime := InitialCountdownTime
は、InitialCountdownTimeを値とするRemainingTimeという名前のオプションを設定しています。
set CountdownTimer = countdown_timer{...}
:
CountdownTimer
という変数に、countdown_timerオブジェクトを代入しています。これにより、CountdownTimerという変数がカウントダウンタイマーオブジェクトを参照するようになります。
このコードを記述する理由としては、おそらくゲームやアプリケーションのロジック上でカウントダウンタイマーの機能を利用するためです。カウントダウンタイマーを操作するためにはインスタンスを作成し、そのインスタンスを変数に代入する必要があります。また、MaybePlayerUIやRemainingTimeなどのオプションを設定することで、カウントダウンタイマーの動作や見た目をカスタマイズできるようになります。
option{PlayerUI}とInitialCountdownTimeである理由
クリックすると開きます。
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
というコードは、CountdownTimerという変数にcountdown_timerという型の値を代入しています。このcountdown_timer型は、MaybePlayerUIとRemainingTimeという2つのフィールドを持つ構造体型を表しています。
MaybePlayerUI := option{PlayerUI}
は、CountdownTimerのフィールドの1つであるMaybePlayerUIに値を代入しています。option{PlayerUI}
は、PlayerUIという値をOption型にラップしている表現です。Option型は、値が存在する場合にSome値を持ち、存在しない場合にNone値を持つデータ型です。MaybePlayerUIにOption型を使用することで、PlayerUIの値が存在するかどうかを明示的に表現できます。
RemainingTime := InitialCountdownTime
は、CountdownTimerのもう1つのフィールドであるRemainingTimeに値を代入しています。ここでは、InitialCountdownTimeという変数の値がRemainingTimeに代入されています。
このようにフィールドへの代入を行うことで、CountdownTimer変数はCountdownTimer型の値を持つことになります。
なぜ2つ
フィールドの選択は、countdown_timer
型の定義に基づいて行われます。
MaybePlayerUI
フィールド:countdown_timer
型は、MaybePlayerUI
というフィールドを持ちます。このフィールドは、PlayerUI
というオブジェクトまたは値が存在するかどうかを表現するために使用されます。option{PlayerUI}
という構文は、PlayerUI
をOption
型にラップすることで、存在する場合はOption
型のSome
値に包まれ、存在しない場合はNone
値となります。これにより、CountdownTimer
がPlayerUI
を持っているかどうかを明示的に表現できます。
RemainingTime
フィールド:- カウントダウンタイマーを表すためには、残り時間を保持するフィールドが必要です。
RemainingTime
フィールドは、カウントダウンタイマーの残り時間を表現し、初期値としてInitialCountdownTime
が代入されます。これにより、カウントダウンタイマーの作成時に初期の残り時間を指定できます。
これらのフィールドは、CountdownTimer
型が表すデータの属性や状態を保持するために使用されます。フィールドの具体的な数や名前は、使用するデータ型に応じて設計されます。
CountdownTimer.StartCountdown()~の詳細
クリックすると開きます。
このコードの「CountdownTimer.StartCountdown()」と「CountdownTimer.CountdownEndedEvent.Await()」の部分は、カウントダウンの処理を開始し、カウントダウンが終了するまで待機するものです。
CountdownTimer.StartCountdown()
:-
CountdownTimer
というオブジェクトのStartCountdown
というメソッドを呼び出します。 - このメソッドは、カウントダウンを開始するための処理を実行します。つまり、カウントダウンが始まります。
CountdownTimer.CountdownEndedEvent.Await()
: CountdownTimer
オブジェクトのCountdownEndedEvent
というイベントを待機します。- イベントは、特別なシグナルであり、カウントダウンが終了したことを通知します。
- "Await()"は、イベントが発生するまで待機するためのキーワードです。
この部分の目的は、カウントダウン処理が行われる間、カウントダウンが完全に終了するまで停止し、次の処理に進まないようにすることです。
カウントダウンが終了すると、次の行である"EndGame.Activate(FirstPlayer)"が実行されます。
"CountdownTimer.StartCountdown()"と"CountdownTimer.CountdownEndedEvent.Await()"の組み合わせは、カウントダウンのような時間を要する処理を実行する際に使われます。例えば、ゲームの制限時間や待ち時間など、時間的制約がある場合に便利です。
countdown_timerクラスのインスタンスを作成するコードでMaybePlayerUIにPlayerUIをオプションの引数として渡す記述をする理由
クリックすると開きます。
countdown_timer
クラスのインスタンスを作成する際に、MaybePlayerUI
にPlayerUI
をオプションの引数として渡す理由は、おそらくプレーヤーがUI(ユーザーインターフェース)を持っている場合にそれを関連付けるためです。
MaybePlayerUI
はオプションの引数であるため、プレーヤーがUIを持っていない場合はNone
(またはnull
などの空値)を設定することができます。これにより、UIが存在しない場合でも、エラーなくカウントダウンタイマーを作成できます。
もしプレーヤーがUIを持っている場合、PlayerUI
をMaybePlayerUI
に関連付けることで、このカウントダウンタイマーが対応するプレーヤーのUIに関連付けられると想定されます。UIを持つプレーヤーの場合、カウントダウンの進捗状況や残り時間などをUI上に表示するために使用されるかもしれません。
countdown_timerクラスのインスタンスを作成する際に、RemainingTimeにInitialCountdownTimeを設定するのはなぜ
countdown_timer
クラスのインスタンスを作成する際に、RemainingTime
にInitialCountdownTime
を設定することは、おそらく初期のカウントダウン時間を設定するためです。
InitialCountdownTime
は、カウントダウンの初期時間を表す変数や定数として想定されます。この初期時間をRemainingTime
に設定することにより、カウントダウンタイマーが最初に開始された時点での残り時間を指定できます。
例えば、InitialCountdownTime
が60と設定されている場合、カウントダウンタイマーが作成された瞬間から始まるカウントダウンの初期時間は60秒になります。
この初期時間は、カウントダウンが開始された後に実際の経過時間に応じて減少していきます。
カウントダウンタイマーを作成する際に初期時間を指定することで、特定の初期値からカウントダウンを開始し、次にカウントダウンが完了するまでの時間を設定することができます。
これにより、カウントダウンの時間を柔軟に制御することができます。
EndGame.Activate(FirstPlayer)の詳細
クリックすると開きます。
「EndGame.Activate(FirstPlayer)」は、指定されたプレイヤーを引数として、「EndGame」というオブジェクトの「Activate」メソッドを呼び出すコードです。
「Activate」メソッドはおそらく「EndGame」オブジェクトの一部であり、ゲームの終了処理を行うために呼び出されるものと想定されます。
上記のコードでは、最初のプレイヤー("FirstPlayer"という変数が使用されています)がカウントダウンを終了した後に「EndGame」をアクティブにするために、「EndGame.Activate(FirstPlayer)」が呼び出されています。
具体的なゲームのルールや仕様に基づく場合、この「EndGame.Activate(FirstPlayer)」の処理はゲームの終了をトリガーし、特定のプレイヤーを結果や勝者とするために使用されるかもしれません。
なお、「EndGame.Activate(FirstPlayer)」について詳しい説明をするためには、プログラムの全体的なコンテキストや「EndGame」オブジェクトの定義、使用方法に関する詳細が必要です。上記のコードだけでは限定された情報しか提供されていないため、詳細な解説ができかねます。
Activateの詳細
「Activate」関数は、ラウンドやゲームの終了処理を行うための関数です。この関数は、「Agent」という引数(変数)を受け取ります。
「Agent」とは、おそらくゲーム内のキャラクターやプレイヤーを表すオブジェクトやエージェントのことであると想像されます。
この「Activate」関数は、与えられた「Agent」を使用してラウンドやゲームを終了させる処理を実行します。また、「Activating Team(アクティブ化チーム)」が有効になっている場合、エージェントの所属チームを使用してラウンドやゲームが終了するかどうかを決定します。
具体的なゲームのルールや要件に応じて、「Activate」関数はさまざまな終了処理を実行することができます。たとえば、エージェントが所属するチームが特定の条件を満たした場合にゲームを終了し、勝者を決定するなどの処理を行うことができます。
ただし、この「Activate」関数の詳細については、提供された情報だけでは限定的であり、ゲーム全体のコンテキストやルールによって変わる可能性があります。ゲームのプログラミングはかなり複雑なため、詳細な解説や具体的なコード例を提供するには、さらなる情報が必要です。
プレイテスト
プレイテストを行うと、カウントダウンが 30 から開始し、タイマーが 0 になるまで毎秒更新されます。
カウントダウンが終了するとすぐにカウントダウンが UI から消え、ゲームは終了します。
プレイヤーがボタンとやり取りすると、カウントダウンに 20 秒が追加され、追加された時間を示すコールアウトが 2 秒間表示されます。
出典:公式ドキュメント
他のコードで使用できるようにクラスを準備する
これで独自のカスタム仕様のカウントダウン タイマー クラスを作成し、タイマーのインスタンス化と制御に Verse で作成した仕掛けを使用しました。
独自のカスタムクラスを作成する場合 (実際にはどのようなコードでもそうですが)、作成したものにアクセスできるものを指定することが重要です。たとえば、カウントダウン タイマーだけがその UI の作成と変更を行えるようにするべきです。Verse では、アクセス指定子 を使用してコードのアクセス レベルを設定できます。
パブリック とは識別子がユニバーサルにアクセス可能であることを意味するため、他のものがアクセスできるようにしたい識別子に public 指定子を追加します。この例では、countdown_timer_example の仕掛けに次のものがすべて使用されているため、これらにはパブリック アクセスが必要です。
出典:公式ドキュメント
- CountdownEndedEvent<public> : event() = event(){}
- StartCountdown<public>() : void =
- AddRemainingTime<public>(Time : float) : void =
プライベート とは、識別子が現在のスコープ、つまりこの識別子を囲んでいるスコープ (この場合、countdown_timer クラス) のみでアクセス可能であることを意味するため、他のものがアクセスできないようにしたい識別子には private 指定子を追加します。
この例では、次のものにプライベート アクセスが必要です。
出典:公式ドキュメント
- RemainingTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}
- AddedTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}
- AddedTimeText<localizes><private>(AddedTime : int) : message = " +{AddedTime}!"
- RemainingTimeText<localizes><private>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
- var Canvas<private> : canvas = canvas{}
- TimerTickPeriod<private> : float = 1.0
- RunCountdown<private>()<suspends> : void =
- AddedTimeCallout<private>(Time : float)<suspends> : void =
- UpdateUI<private>() : void =
コンストラクタ を使用すると、クラスの変数を 公開 することなく、新しいクラス インスタンスの初期値を設定することができます。コンストラクタは、関連付けられているクラスのインスタンスを作成する特別な関数です。
RemainingTime と MaybePlayerUI 変数を更新する countdown_timer クラスのためのコンストラクタを作成します。
出典:公式ドキュメント
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
コンストラクタで設定された変数 RemainingTime と MaybePlayerUI は、パブリック アクセスを無効にするべきですが、コンストラクタで設定されている場合はプライベート アクセスを有効にできません。これらの変数には internal 指定子を使用できます。これは、現在のモジュール、つまりこの識別子を囲んでいるモジュール内のみでこの識別子にアクセスできることを意味します。
出典:公式ドキュメント
- MaybePlayerUI<internal> : ?player_ui = false
- var RemainingTime<internal> : float = 0.0
まとめ:完全なスクリプト
今回は、カスタム仕様のカウントダウンタイマー(2)を解説しました。
countdown_timer.verse
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /Fortnite.com/UI }
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
countdown_timer := class:
<# このブロックは、countdown_timer class のインスタンスごとに実行されます。
ここに到達した際にキャンバスを設定できます。#>
block:
set Canvas = canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.4, Y := 0.3}
Maximum := vector2{X := 0.6, Y := 0.3}
Alignment := vector2{X := 0.5, Y := 0.5 }
Offsets := margin{Top := 0.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
SizeToContent := true
Widget := RemainingTimeTextBlock
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.4, Y := 0.3}
Maximum := vector2{X := 0.6, Y := 0.3}
Alignment := vector2{X := 0.0, Y := 1.0}
Offsets := margin{Top := 0.0, Right := 0.0}
SizeToContent := true
Widget := AddedTimeTextBlock
CountdownEndedEvent<public> : event(float) = event(float){}
StartCountdown<public>() : void =
if (PlayerUI := MaybePlayerUI?):
PlayerUI.AddWidget(Canvas)
# タイマーの開始時に UI を更新して、画面に RemainingTime の初期値を表示します
UpdateUI()
spawn:
RunCountdown()
AddRemainingTime<public>(Time : float) : void =
set RemainingTime += Time
# 時間が追加された際に UI を即座に更新して、より優れたプレイヤー フィードバックを実現します。
UpdateUI()
# シンプルなコールアウトを起動して、追加される時間を表示します。
spawn:
AddedTimeCallout(Time)
MaybePlayerUI<internal> : ?player_ui = false
var RemainingTime<internal> : float = 0.0
RemainingTimeTextBlock<private> : text_block = text_block{}
AddedTimeTextBlock<private> : text_block = text_block{}
RemainingTimeText<localizes><private>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
AddedTimeText<localizes><private>(AddedTime : int) : message = " +{AddedTime}!"
var Canvas<private> : canvas = canvas{}
var TotalTime<private> : float = 0.0
# タイマーの「精度」を表し、ティックの頻度を秒単位で表します。
TimerTickPeriod<private> : float = 1.0
RunCountdown<private>()<suspends> : void =
# TimerTickPeriod を使ってループします。
# UI も毎回更新されます。
loop:
Sleep(TimerTickPeriod)
set TotalTime += TimerTickPeriod
set RemainingTime -= TimerTickPeriod
UpdateUI()
# タイマーの終了
if (RemainingTime <= 0.0):
Canvas.RemoveWidget(RemainingTimeTextBlock)
if (UI := MaybePlayerUI?):
UI.RemoveWidget(Canvas)
CountdownEndedEvent.Signal(TotalTime)
break
AddedTimeCallout<private>(Time : float)<suspends> : void =
if:
PlayerUI := MaybePlayerUI?
IntTime := Int[Time]
then:
AddedTimeTextBlock.SetVisibility(widget_visibility.Visible)
AddedTimeTextBlock.SetText(AddedTimeText(IntTime))
Sleep(2.0)
AddedTimeTextBlock.SetVisibility(widget_visibility.Hidden)
UpdateUI<private>() : void =
if (IntTime := Int[RemainingTime]):
RemainingTimeTextBlock.SetText(RemainingTimeText(IntTime))
countdown_timer_example.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
countdown_timer_example := class(creative_device):
@editable
AddMoreTimeButton : button_device = button_device{}
@editable
EndGame : end_game_device = end_game_device{}
var CountdownTimer : countdown_timer = countdown_timer{}
InitialCountdownTime : float = 30.0
OnBegin<override>()<suspends> : void =
AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith)
if:
FirstPlayer := Self.GetPlayspace().GetPlayers()[0]
PlayerUI := GetPlayerUI[player[FirstPlayer]]
then:
set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime}
CountdownTimer.StartCountdown()
CountdownTimer.CountdownEndedEvent.Await()
EndGame.Activate(FirstPlayer)
else:
Print("Can't find player")
OnButtonInteractedWith(Agent : agent) : void =
TimeToAdd : float = 20.0
CountdownTimer.AddRemainingTime(TimeToAdd)
今回もお疲れさまでした🍵