階層的タグ付けはコンセプトとデータを整理するうえで非常に便利な方法です。Gameplay Tag システムは、UE4 で階層的タグを宣言し、クエリするためのものです。Gameplay Tag のバージョンはいくつかありますが、UE4.15 ではインターフェースとパフォーマンスが大幅に向上しました。是非、この機会にお試しください。ところで、Gameplay Tag とはどんなもので、何に使うのでしょうか?
ゲームプレイ タグは、“Family.Genus.Species.Subspecies” または “IndividualTag” の形式の名前になります。これらのタグは内部で FName として実装され、バリデーションのためにベースとなる辞書に登録されています。 ‘.’ を使って名前をネスティングすることで、正確なタグを探すクエリーが可能になります。また、親のタグを含むタグを探すクエリーも可能になります。例えば、2 つのアイテムに “Weapon.Ranged” と “Weapon.Melee” とタグ付けされていれば、両方で MatchesTag(“Weapon”) が true になります。MatchesTagExact(“Weapon”) は両方で false になります。完全一致は親のタグを無視するからです。
Gameplay Tag Container は、Gameplay Tag のセットであり、複数のタグを同時にクエリーするために使用可能です。タグは具体的に追加されている場合のみ Exact チェックをパスしますが、すべての親タグは通常のチェックに含まれます。Container.AddTag(“Weapon.Melee”) と Container.AddTag(“Spell.Fireball”) を呼び出すと、Container.HasTagExact() は “Weapon.Melee” と ”Spell.Fireball” でのみ true になります。 Container.HasTag() は、 “Weapon”、 “Weapon.Melee”、 “Spell”、および “Spell.Fireball” で true になります。
Gameplay Tag は何に役立ちますか? まず、Name の代わりに、Name と Enum の組み合わせと同様にデザイナーが有効な名前だけを入力するようにテキストを制限する場合に使えます。こうした階層機能は Paragon のようなゲームで使われ、ネスティング構造を持つ Damage Type のようなものを表現します。例えば、“Damage.DoT.Burn” は Fire Damage Over Time (時間の経過に伴いダメージを与える) 機能を行う場合に渡されます。これでブループリントまたはネイティブ コードを登録して “Damage”、“Damage.DoT”、または “Damage.DoT.Fire” を探します。この 3 つが特定の場合に発生します。
タグの登録
ゲームプレイ タグを使うには、ベースとなるタグ辞書に登録しなければいけません。辞書への追加方法は以下のとおりです。主な方法として ini ファイルの使用、またはデータ テーブルの使用の 2 つがあります。いずれかの方法でセットアップするには、Project Settings UI で GameplayTag のタブを開きます。すると、タグ管理の UI が開きます。
ini ファイルを使ってタグを追加するには “Import Tags From Config” オプションを有効にします。これで GameName/Config/DefaultGameplayTags.ini からタグと GameName/Config/Tags にある ini ファイルをロードします。プロジェクトの誰でも簡単にタグを追加できるようにしたい場合はこの方法を使います。一度これを行うと、タグ管理 UI またはタグ選択インターフェースから [Add New Tag ] ボタンを使って新規タグを追加することができます。既存のタグの隣にある + アイコンを押すか、Add New Gameplay Tag セレクタを開きます。
外部のタグ リストをインポートする場合、GameplayTagTableRow タイプの DataTable を使ってタグを追加することもできます。これを行うには、DataTable をインポートしてから、それを Tags settings UI にある GameplayTagTableList に追加します。プロジェクトのスタートアップ中に AddNativeGameplayTag を使ってネイティブ コードから直接追加することもできます。
タグが辞書に入ったら、参照のために検索、タグを削除、タグ名を変更したりして管理することができます。こうした操作をするには、管理ビューでタグのとなりにある下向き三角のドロップダウンを使用します。タグは ini ファイルで追加した場合のみ削除可能であり、他のものから参照できません。名前変更したタグは、GameplayTagRedirects リストに入り、名前変更したタグがあればロード中に修正されます。References を検索すると、Reference Viewer が開き、指定したタグを使用するすべてのアセットが表示されます。
タグの使用
タグを実際に使用するには、何かをタグ付けする必要がありまます。まず、ブループリントやネイティブ型に GameplayTag またはGameplayTagContainer のプロパティを追加します。タグ付けされているものが単一値のみを持つことができる場合、単一の GameplayTag を使用します (例えば、“Color.Blue” を UI Color 構造体に追加することができます。一度に複数の Color にはならないからです)。複数種類のステートまたは値に対応する場合はコンテナを使用します (例えば、npc は “Character.NPC”、 “Character.Humanoid”、および “Gameplay.Important” とタグ付けすることができます)。こうしたプロパティを追加したら、ブループリントのデフォルト ビューまたは アセット エディタで編集することができます。
これでタグ付けできたので、こうしたタグを使ってクエリーし、ゲームプレイ コードからフィルタリングすることができます。C++ から GameplayTagContainer.h で定義された操作を使用することができます。重要なものとしては、次のものが挙げられます。個々の GameplayTag の MatchesTag、 MatchesAny、 IsValid、および GetTagName があります。また GameplayTagContainer の HasTag、 HasAny、 HasAll、 AddTag、および RemoveTag があります。Tag matching 関数は親のタグに対してマッチングしますが、Exact バリアントは特定のタグだけをマッチングします。
ブループリントから同じ操作にアクセスできますが、Exact オプションは matching 関数に渡される bool です。以下は Make Literal Gameplay Tag ノードを使い、Tag Container に渡されたものが親を含むタグと一致するかを確認する基本的な例です。
“Switch on Gameplay Tag Container” や “Compare Tag Container To Other Tag Containers” などの高度なノードも GameplayTag カテゴリにあります。4.15 より前もこうした操作は可能でしたが、面倒なシンタックスや UI を使用しなければなりませんでした。
以上が Gameplay Tag をゲームに統合する方法の概要です。他の方法でエンジンに Gameplay Tag を統合する方法を計画中ですが、現行ツールを使って構築しても安定した基盤になるはずです。エピックの Paragon や他の社内のゲームの出荷にはGameplay タグの使用が欠かせません。こうしたものが皆さんのゲームの新たなデザインやプログラミングの選択肢の可能性を開くことになれば幸いです。