このようなプレイヤーの高さを表示する仕組みを作っていきます。
コードの全体
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/UI }
using { /Verse.org/Simulation }
using { /Verse.org/Colors }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
distance_device := class(creative_device):
UIText<localizes>(Value : string) : message = "{Value}"
(Player : player).InitUI() : void =
TextWidget : text_block = text_block{ DefaultTextColor:= NamedColors.White}
NewCanvas : canvas = canvas:
Slots := array:
canvas_slot:
Widget := TextWidget
Anchors := anchors{ Minimum := vector2{ X := 0.5, Y := 0.8}, Maximum := vector2{ X := 0.5, Y := 0.8}}
if (PlayerUI := GetPlayerUI[Player], FortCharacter := Player.GetFortCharacter[]):
PlayerUI.AddWidget(NewCanvas)
spawn:
FortCharacter.UpdateDistance(TextWidget)
(FortCharacter : fort_character).UpdateDistance( TextBlock : text_block)<suspends> : void =
loop:
Sleep(0.4)
DistanceVerticalMeters := FortCharacter.GetTransform().Translation.Z / 100.0
if (RoundedDistance := Floor[DistanceVerticalMeters] ):
TextBlock.SetText(UIText("- {RoundedDistance}m -"))
HandlePlayerJoin (Agent : agent) : void =
if (Player := player[Agent]):
Player.InitUI()
OnBegin<override>()<suspends>:void=
GetPlayspace().PlayerAddedEvent().Subscribe(HandlePlayerJoin)
for (Player : GetPlayspace().GetPlayers()):
Player.InitUI()
コードの解説
関数宣言
12行目で、UIのテキストを決定するUIText関数を定義しています。
String型の値を引数として呼び出すことでmessage型の値に変換できます。
15行目からplayer型を対象とするInitUIメソッドを定義しています。
コードブロックの意味は以下のようになります。
16行目でtext_blockクラスのインスタンスを作成しています。
text_blockクラスのメンバーにDefaultTextColorはありませんがtext_blockクラスの親クラスであるtext_baseクラスのメンバーにDefaultTextColorが存在します。
そして、NamedColorsモジュールのメンバーであるWhiteにアクセスして、文字の色を白に設定します。
17行目以降は表示するUIの位置やテキストの設定です。
CanvasはクラスでありそのインスタンスをNewCanvasとして作成していますが、クラスのメンバーのSlotsは配列であり、また、Slotsの型のcanvas_slotは構造体であるため、難解な式になっています。
Slotと言う単語は日本語で位置という意味ですので、ここでUIの位置が設定されます。
19行目からcanvas_slotの構造体のインスタンスを作成していますが、 Widgetメンバーには、表示するテキストの情報を設定します。(今回のコードではテキストの色しか入っていません。テキストの文字の情報はUpdateDistanceで追加されます。)
Anchorsメンバーには、表示する位置を設定しています。(厳密にはAnchorsを設定し、Offsetsというメンバーでアンカーからの距離を決めて、UIの位置を決めるのですが、今回はOffsetsが未設定のため、アンカーの位置がUIの位置となります。)
以下の記事でcanvas_slotのメンバーについて書いているので合わせてお読みください。
23行目以降でプレイヤーのplayer情報からplayer_ui情報、fort_character情報を取得し、player_ui情報に対してAddWidgetを呼び出すことでゲーム画面にUIを表示します。
そして、fort_characterを対象にUpdateDistanceを呼び出しています。
30行目からUpdateDistanceメソッドを宣言しています。
コードブロックの意味は以下のようになります。
この関数の中でasyncな関数(処理に時間がかかる)であるSleep関数が使われているため、この関数自体がasyncとなります。
asyncな関数の定義時には、そのことを示すためにsuspends指定子を書きます。
パラメーターによりInitUIで設定したテキストに関する情報を引き継いでいるため、それに、現在のプレイヤーの高さをテキストとして追加します。
これを、高速でループさせることで現在の高さ更新させ続けています。
FortCharacterを対象にGetTransformメソッドを呼び出し、プレイヤーのtransform情報(位置、回転、拡大)を取得し、その情報に対してTranslationメンバーにアクセスして、位置情報(vector3型)だけを抜き出しています。
そしてさらに、vector3構造体のZメンバーにアクセスしてz座標、つまり高さの情報を抜き出しています。
この高さ情報の単位はcmなので、mとして表示したいため÷100します。
35行目で、Floor関数で端数を切り捨てます。
この数値をUIText関数を通して、message型に変換しUIのテキストとなります。
39行目から途中参加したプレイヤーにもこの仕組みを適用するためのHandlePlayerJoin関数を定義しています。
コードブロックの意味は以下のようになります。
OnBegin~
44行目からのコードなゲーム開始時に実行されますが、
コードブロックの意味は以下のようになります
以下のように動けば完成です。
コメント