[UEFN][verse]グローバル変数を使いたい[2]ゲームプレイタグ(レベルに配置されたオブジェクトをクエリする仕組み)
今回はゲームプレイタグ(通称「タグ」)について。以前、グローバル変数の機能を導入するために考案された(しかし今はもう使えない)シングルトンについて説明しましたが、タグは似たような機能を持ち、かつ公式に推奨されている手法です。
注意
時間がなくて一部のコードが実機検証できていません。後で試して問題があったら更新します。
ゲームプレイタグ
「ゲームプレイタグ(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_view
のHas()
/HasAll()
/HasAny()
メソッドで、タグの設定有無を確認できます。
#MyTag1が設定されていれば成功。そうでなければ「失敗」
TagView.Has(mytag{})
#MyTag1とMyTag2の両方が設定されていれば成功。そうでなければ「失敗」
TagView.HasAll(array{mytag{}, mytag_sub{}})
#MyTag1とMyTag2のいずれかが設定されていれば成功。そうでなければ「失敗」
TagView.HasAny(array{mytag{}, mytag_sub{}})
続き
お知らせ
verse言語とUEFNの記事を他にも書いているので御覧下さい。
最後まで読んで頂きありがとうございました。この記事がお役に立てたようであれば、是非LIKEとフォローをお願いします(今後の執筆のモチベーションに繋がります)。
#Verse #UEFN #Fortnite #Verselang #UnrealEngine
宣伝
「Unityシェーダープログラミングの教科書」シリーズ1~5をBOOTHで頒布中です。
Discussion