🕌

[UEFN][verse]グローバル変数を使いたい[2]ゲームプレイタグ(レベルに配置されたオブジェクトをクエリする仕組み)

2023/07/06に公開

今回はゲームプレイタグ(通称「タグ」)について。以前、グローバル変数の機能を導入するために考案された(しかし今はもう使えない)シングルトンについて説明しましたが、タグは似たような機能を持ち、かつ公式に推奨されている手法です。

注意

時間がなくて一部のコードが実機検証できていません。後で試して問題があったら更新します。

ゲームプレイタグ

ゲームプレイタグ(Gameplay Tags)」は、レベルに配置したオブジェクトを「タグ(Tag)」で識別し、検索する為の仕組みです。様々な用途が考えられますが、現状ではverseでグローバル変数に相当する機能を実現する唯一の方法だと思います。

タグはVerse上で定義した後、UEFNエディタ上でレベル内のオブジェクトに割り当てます。この割当は各オブジェクトにタグ割当用のコンポーネントを追加して行います。コンポーネントの割当は現状のverseでは実行出来ないので、必然的にタグの設定は予めレベルに配置されているオブジェクトに限られます[1]

タグの定義

タグの定義にはtagクラスを使用します。tagクラスはTagsモジュールに含まれるので、インポートが必要です。

using { /Verse.org/Simulation/Tags }

tagクラスの派生クラスを定義すると、そのクラス名がユーザー定義タグになります。下のコードではmytagタグを定義しています。

mytag := class(tag){}

派生クラスを更に派生することで、タグを階層化できます(階層化ついては後述します)。

mytag_sub := class(mytag){}
mytag_sub_child := class(mytag_sub){}

ここではmy_tag<mytag_sub<mytag_sub_childという階層構造を定義しました。

余談ですがタグの名称について。公式ドキュメントではアンダーバーで階層を区切る書式を推奨していますが、これは絶対的なルールではありません[2]。この記事では公式を踏襲します。

タグの設定

UEFNに移動してVerseをビルド[3]すると、定義したタグが使用可能になります。
 あるオブジェクトにタグを設定する場合、そのオブジェクトにVerseTagMarkupコンポーネントを追加します。
 下図は、creative_deviceの詳細タブの「追加」ボタンを押した所です。

ドロップダウンリストの下の方にある「Verse Tag Markup」を選択するとVerseTagMarkupコンポーネントが追加されます。

"Edit"の右側の矢印をクリックすると選択可能なタグのリストが表示されます。リストには組み込みのタグも表示されます 。階層化したタグは最初折りたたまれているので展開してください。

リストの中から、このオブジェクトに設定するタグを指定します。複数のタグを設定する事もできます。

「Show Tag Hierarchy」にチェックを入れると、選択リストに階層構造が表示されます[4]

なお、階層の下位のタグを設定した場合、下図のように自動的にその階層の上位タグが全て設定されている物と見なされます(後述)。

タグの検索

タグを設定したオブジェクトは、verse上で検索をかけることができます。

タグの検索には「レベル全体から任意のタグが設定されたオブジェクトを抽出する方法」と「特定のオブジェクトが任意のタグが設定されているかを判定する方法」の2種類があります。それぞれ見ていきましょう。

タグが設定されたオブジェクトを抽出する方法

1個のタグを検索(GetCreativeObjectsWithTag()メソッド)

タグの検索にはGetCreativeObjectsWithTag()メソッドを使います。このメソッドはDevicesモジュールに含まれます。

using { /Fortnite.com/Devices }

メソッドのインターフェイスは以下のようになっています(エフェクト指定子は省略)。

GetCreativeObjectsWithTag(Tag:tag):[]creative_object_interface

検索したいtagを引数に指定すると、そのタグを持つオブジェクトが配列にして返します。この配列を型変換して参照します。

TaggedActors := GetCreativeObjectsWithTag(mytag{})
for:
    MyTagObject : TaggedActors
    Button:=button_device[MyTagObject]
do:
    #Buttonにアクセスする

階層化されたタグを指定すると、階層配下のタグも検索対象になります。

#mytag_sub_childのみを検索
TaggedActors := GetCreativeObjectsWithTag(mytag_sub_child{})

#mytag_sub/mytag_sub_childを検索
TaggedActors := GetCreativeObjectsWithTag(mytag_sub{})

#mytag/mytag_sub/mytag_sub_childを検索
TaggedActors := GetCreativeObjectsWithTag(mytag{})

複数のタグを検索(GetCreativeObjectsWithTags()メソッド)

GetCreativeObjectsWithTags()メソッド(末尾に"s"がある)を使うと、複数のタグを使って絞り込むことも出来ます。

インターフェースはこちら。引数のtag_search_criteriaクラスに複数のタグのクエリ条件が格納されます。

GetCreativeObjectsWithTags(SearchCriteria:tag_search_criteria):[]creative_object_interface

tag_search_criteriaクラスの設定の例を幾つか示します[5]

# mytagとMyTag2の両方が設定されているオブジェクト[AND]
        ObjWithMyTagAndMyTagSub := GetCreativeObjectsWithTags(
            tag_search_criteria{
                RequiredTags := array{mytag{}, mytag_sub{}}
            }
        )

# mytagとMyTag2のいずれか一つでも設定されているオブジェクト[OR]
ObjWithMyTagOrMyTagSub := GetCreativeObjectsWithTags(
    tag_search_criteria{
	PreferredTags := array{mytag{}, mytag_sub{}}
    }
)

# MyTag1とMyTag2のいずれかが設定されていて、MyTag3が設定されていないオブジェクト[NOT]
ObjWithMyTagOrMyTagSubButNotMyTagSubChild := GetCreativeObjectsWithTags(
    tag_search_criteria{
	PreferredTags := array{mytag{}, mytag_sub{}}, 
	ExclusionTags := array{mytag_sub_child{}}
    }
)

特定のオブジェクトにタグが設定されているかを判定する方法

GetTags()拡張メソッドを使うと、オブジェクトに設定されているタグの情報が格納されたtag_viewオブジェクトを取得できます。

TagView :tag_view = Button.GetTags()

tag_viewHas()/HasAll()/HasAny()メソッドで、タグの設定有無を確認できます。

#MyTag1が設定されていれば成功。そうでなければ「失敗」
TagView.Has(mytag{})

#MyTag1とMyTag2の両方が設定されていれば成功。そうでなければ「失敗」
TagView.HasAll(array{mytag{}, mytag_sub{}})

#MyTag1とMyTag2のいずれかが設定されていれば成功。そうでなければ「失敗」
TagView.HasAny(array{mytag{}, mytag_sub{}})

続き

https://zenn.dev/t_tutiya/articles/c5569cc9698ea7

お知らせ

verse言語とUEFNの記事を他にも書いているので御覧下さい。
https://zenn.dev/t_tutiya

最後まで読んで頂きありがとうございました。この記事がお役に立てたようであれば、是非LIKEとフォローをお願いします(今後の執筆のモチベーションに繋がります)。

#Verse #UEFN #Fortnite #Verselang #UnrealEngine

宣伝

「Unityシェーダープログラミングの教科書」シリーズ1~5をBOOTHで頒布中です。
https://s-games.booth.pm/

脚注
  1. 多分。将来的には対応されるかも ↩︎

  2. fortniteライブラリの組み込みのタグでもこのルールは守ってない ↩︎

  3. 土屋はCtrl+Shift+Bでビルドしています ↩︎

  4. バグなのか、このチェックボックスはちょくちょくリセットされる印象 ↩︎

  5. ここで示した以外にSortTypeというフラグがあるのだけど挙動がよくわからない ↩︎

Discussion