【UEFN】Verse言語で「Only Up のプレイヤーの高さを表示する仕組み」を実装する

このようなプレイヤーの高さを表示する仕組みを作っていきます。

目次

コードの全体

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メソッドを定義しています。 
コードブロックの意味は以下のようになります。 

1.テキストの色を白に決定 
2.表示するUIの位置やテキストを決定
3.Player情報からplayer_ui情報、fort_character情報を取得 
4.プレイヤーの画面にUI表示 
5.UpdateDistanceを呼び出す 

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メソッドを宣言しています。 
コードブロックの意味は以下のようになります。 

以下をループ
1.コードの処理を0.4秒間停止 
2.プレイヤーが何m高さにいるか取得 
3.端数を切捨てる 
4.その高さの数値を、UIのテキストに設定する

この関数の中でasyncな関数(処理に時間がかかる)であるSleep関数が使われているため、この関数自体がasyncとなります。
asyncな関数の定義時には、そのことを示すためにsuspends指定子を書きます。 

パラメーターによりInitUIで設定したテキストに関する情報を引き継いでいるため、それに、現在のプレイヤーの高さをテキストとして追加します。 
これを、高速でループさせることで現在の高さ更新させ続けています。 

FortCharacterを対象にGetTransformメソッドを呼び出し、プレイヤーのtransform情報(位置、回転、拡大)を取得し、その情報に対してTranslationメンバーにアクセスして、位置情報(vector3型)だけを抜き出しています。


そしてさらに、vector3構造体のZメンバーにアクセスしてz座標、つまり高さの情報を抜き出しています。


この高さ情報の単位はcmなので、mとして表示したいため÷100します。 

35行目で、Floor関数で端数を切り捨てます。 

この数値をUIText関数を通して、message型に変換しUIのテキストとなります。 


39行目から途中参加したプレイヤーにもこの仕組みを適用するためのHandlePlayerJoin関数を定義しています。 
コードブロックの意味は以下のようになります。 

途中参加したプレイヤーのplayer情報を取得してInitUI関数を実行する

OnBegin~

44行目からのコードなゲーム開始時に実行されますが、
コードブロックの意味は以下のようになります 

1.PlayerAddedEventが起きたら(ゲームに新たにプレイヤーが参加したら)HandlePlayerJoin関数を呼び出す 
2.ゲーム内にいる全てのプレイヤーのplayer情報を取得し、各プレイヤーを対象にInitUIを呼び出す 



以下のように動けば完成です。

よかったらシェアしてね!

この記事を書いた人

メタバースに興味を持ち、UEFN、Verseを学びながらFortniteでゲーム制作しています。
初心者でも理解できるような記事を書くことを心がけております。
間違いがありましたら指摘よろしくお願いいたします。

コメント

コメントする

目次