敵の種類をEnumで管理していたら、新しい敵を出すたびにEnumを開くことになった。さらに「アンデッドにだけ効く聖水」を作ろうとして、Switch on Enum の分岐がスケルトン・ゾンビ・グールと並び、敵が増えるたびに聖水のBlueprintも直しに行く。
小さな試作ならそれでも動きます。ただ、種類が増えるほど「敵を1体足す作業」が「あちこちを直す作業」に変わっていきます。これを解きほぐす道具が Gameplay Tag です。この記事では、Enemy.Undead.Skeleton のような階層つきの名札で敵を分類し、種類が増えても判定側を書き換えずに済む形を、Blueprint中心に解説します。
この記事でわかること
- Gameplay Tag =
.で階層をつけた名札- Enum・Nameとの決定的な違いは 親タグでの一括判定
- Project Settingsでの追加と、
DefaultGameplayTags.iniでの管理- Has Tag / Has Any Tags / Has All Tags / Matches Tag の使い分け
- 実践:敵を増やしても書き換え不要な アンデッド特効の聖水
Enumが破綻するところ
Enumは「候補が決まっている値」を扱うのに向いた仕組みです。敵が3種類しかいないうちは、これで何の問題もありません。
問題が出るのは 分類が増えたときと、まとめて扱いたくなったとき です。

E_EnemyType に Skeleton を足すと、Switch on Enum を使っている全Blueprintに新しいピンが生えます。聖水も、聖属性の魔法も、ネクロマンサーの蘇生も、全部開 いて繋ぎ直しです。 敵を1体足すたびに、敵と無関係なアセットを触ることになります。
さらにEnumは平坦です。「アンデッド全般」という中間のまとまりを表現できないので、「スケルトンまたはゾンビまたはグールなら」と列挙し続けるしかありません。
Name(文字列)で管理すれば追加は自由ですが、今度はタイポが実行時まで気づけません。"Undead" と "undead" のどちらで書いたか覚えていられなくなります。
Gameplay Tagは、この2つの弱点をどちらも埋めます。 追加が自由で、タグは辞書から選ぶので綴りを間違えず、しかも階層でまとめて扱えます。
Gameplay Tagは階層つきの名札
Gameplay Tagは、.(ドット)で区切った階層を持つラベルです。

Enemy
├─ Enemy.Undead
│ ├─ Enemy.Undead.Skeleton
│ ├─ Enemy.Undead.Zombie
│ └─ Enemy.Undead.Ghoul
└─ Enemy.Beast
├─ Enemy.Beast.Wolf
└─ Enemy.Beast.Bear
決定的なのは 子タグは親タグにも一致する という性質です。Enemy.Undead.Skeleton を持つ敵に対して Enemy.Undead で判定すると true が返ります。Enemy で判定しても true です。
この一方通行が効きます。「アンデッドに効く」処理は Enemy.Undead を見るだけでよく、後から Enemy.Undead.Wraith を追加しても、 処理側は一文字も変わりません 。
逆向きは成立しません。Enemy.Undead しか持たない敵に Enemy.Undead.Skeleton で判定すると false です。 親で問えば広く当たり、子で問えば狭く当たる と覚えてください。
タグは敵の種類だけでなく、状態や能力にも使えます。
| 使いどころ | タグの例 |
|---|---|
| 種族・分類 | Enemy.Undead.Skeleton |
| 状態 | Status.Debuff.Poison / Status.Stunned |
| 属性・耐性 | Damage.Type.Holy / Immune.Fire |
| 装備の分類 | Item.Weapon.Sword.TwoHanded |
Gameplay TagはGameplay Ability System(GAS)でも中核として使われていますが、 GASを導入しなくても単体で使えます 。この記事はGASを前提にしません。GAS自体を入れるべきか迷ったら Gameplay Ability System入門 が判断の助けになります。
タグを追加する2つの方法
タグは使 う前に 辞書へ登録 します。登録していないタグは、Blueprintのプルダウンに出てきません。

方法1:Project Settingsから追加する
普段はこちらです。
Edit→Project Settings→ProjectカテゴリのGameplayTagsを開くGameplay Tagsの+(Add New Gameplay Tag) をクリックNameにEnemy.Undead.Skeletonと フルパスで 入力するCommentに用途を書き、Add New Tagで確定
Enemy と Enemy.Undead を先に作る必要はありません。 フルパスを入力すれば中間の階層は自動で作られます 。
登録済みのタグは右クリックから名前変更・削除・子タグの追加ができます。 名前変更(Rename)は参照を追従してくれるので、直接iniを書き換えるより安全です。
方法2:iniファイルで管理する
追加したタグは、既定でプロジェクトの Config/DefaultGameplayTags.ini に保存されます。
[/Script/GameplayTags.GameplayTagsSettings]
+GameplayTagList=(Tag="Enemy.Undead.Skeleton",DevComment="骨の敵")
+GameplayTagList=(Tag="Enemy.Undead.Zombie",DevComment="腐った敵")
+GameplayTagList=(Tag="Enemy.Beast.Wolf",DevComment="獣の敵")
テキストなのでバージョン管理の差分が読めるのが利点です。エディタを閉じた状態で直接編集することもできます。
規模が大きくなったら、Project Settingsのタグ追加時に Source を切り替えて 機能ごとに別のiniへ分ける と、チームで同じ行を編集する競合を減らせます。
C++で定義する選択肢もあります。
NativeGameplayTags.hのUE_DECLARE_GAMEPLAY_TAG_EXTERN/UE_DEFINE_GAMEPLAY_TAG_COMMENTを使うと、C++コードからタグを変数として参照でき、綴りの誤りがコンパイル時に見つかります。使う場合はBuild.csのPublicDependencyModuleNamesに"GameplayTags"の追加が必要です(→ BlueprintからC++への第一歩)。
判定ノードの使い分け
Blueprintで扱う型は2つです。
| 型 | 中身 | 使いどころ |
|---|---|---|
| Gameplay Tag | タグ 1つ | 「このダメージの属性」など、1つに決まるもの |
| Gameplay Tag Container | タグの 集合 | 「この敵が持つ性質」など、複数持つもの |

判定ノードは、対象がコンテナか単体かで名前が変わります。
| ノード | 対象 | 判定内容 |
|---|---|---|
| Has Tag | コンテナ | 指定タグ またはその子 を持つか |
| Has Any Tags | コンテナ | 指定した複数タグの どれか1つでも 持つか |
| Has All Tags | コンテナ | 指定した複数タグを すべて 持つか |
| Matches Tag | 単体タグ | そのタグが指定タグ またはその子 か |
具体例で見ます。敵が Enemy.Undead.Skeleton と Status.Debuff.Poison の2つを持っている場合です。
| 問い合わせ | 結果 |
|---|---|
Has Tag(Enemy.Undead) | true(子タグなので一致) |
Has Tag(Enemy.Beast) | false |
Has Any Tags(Enemy.Undead, Enemy.Beast) | true(片方だけ一致すればよい) |
Has All Tags(Enemy.Undead, Status.Debuff) | true(両方一致) |
Has All Tags(Enemy.Undead, Immune.Fire) | false |
「〜に効く」は Has Tag 、「〜か〜に効く」は Has Any Tags 、「〜かつ〜のときだけ」は Has All Tags です。
完全一致で判定したいときは
Exact版を使います。Has Tag Exactは階層を無視し、Enemy.Undead.Skeletonに対してEnemy.Undeadで問うとfalseを返します。「アンデッド全般ではなく、スケルトンだけ」という限定が必要なときの選択肢です。
空のコンテナには落とし穴があります。 判定に渡すタグの集合が空の場合、
Has Any Tagsはfalseを返しますが、Has All Tagsは「欠けているタグがない」と解釈されてtrueを返します。条件をデータから流し込む設計にするときは、空のケースを一度確かめてください。
実践:アンデッド特効の聖水を作る
ローグライクの属性特効アイテム、ホラーゲームの浄化アイテム、タワーディフェンスの対空専用タワー。 「特定のグループにだけ強く効く」 という仕組みは、ジャンルを問わず登場します。ここでは、敵の種類を増やしても聖水側を一切触らずに済む形を組み立てます。

再現用の準備: Third Person テンプレートで新規プロジェクトを作ります。あらかじめProject Settingsで次の4つのタグを登録しておきます。
Enemy.Undead.Skeleton
Enemy.Undead.Zombie
Enemy.Beast.Wolf
Damage.Type.Holy
| 種類 | 名前 | 型 / 初期値 |
|---|---|---|
| Blueprint Class(Actor) | BP_EnemyBase | 3体の親クラス |
BP_EnemyBase の変数 | EnemyTags | Gameplay Tag Container / 空。 Instance Editable をオン |
BP_EnemyBase の変数 | Health | Float / 100.0 |
| 子Blueprint | BP_Skeleton | EnemyTags の既定値に Enemy.Undead.Skeleton |
| 子Blueprint | BP_Zombie | EnemyTags の既定値に Enemy.Undead.Zombie |
| 子Blueprint | BP_Wolf | EnemyTags の既定値に Enemy.Beast.Wolf |
| Blueprint Class(Actor) | BP_HolyWater | Sphere Collision(Radius 200.0)を持つ |
BP_HolyWater の変数 | BaseDamage | Float / 20.0 |
BP_HolyWater の変数 | HolyMultiplier | Float / 5.0 |
BP_HolyWater の変数 | TargetTag | Gameplay Tag / 既定値 Enemy.Undead 。 Instance Editable をオン |
ステップ1:敵の親クラスを作る。 コンテンツブラウザで右クリック → Blueprint Class → Actor 。BP_EnemyBase と名付けます。
My Blueprintパネルで変数を2つ追加します。EnemyTags は型のプルダウンで Gameplay Tag Container を選びます。Health は Float にして、詳細パネルの Default Value に 100.0 を入れます。両方とも Instance Editable にチェックを入れておくと、レベルに置いた個体ごとにタグを足せます。
ステップ2:敵を3体作る。 BP_EnemyBase を右クリック → Create Child Blueprint Class で3つ作ります。それぞれを開き、EnemyTags の Default Value の + からタグを選びます。 プルダウンには登録済みのタグしか出てこないので、ここで綴りを間違えることはありません。
ステップ3:ダメージ処理を親クラスに書く。 BP_EnemyBase に ApplyHolyDamage というカスタムイベントを作り、入力に Damage(Float)を追加します。中身は Health から Damage を引いて設定するだけです。
ステップ4:聖水のBlueprintを組む。 BP_HolyWater を作り、Sphere Collision コンポーネントを追加して Sphere Radius を 200.0 にします。変数3つを上の表のとおりに用意し、On Component Begin Overlap から次のグラフを組みます。

BP_HolyWater
On Component Begin Overlap (Sphere)
→ Cast To BP_EnemyBase(Object: Other Actor)
成功 → Get EnemyTags(As BP Enemy Base から)
→ Has Tag(Container: EnemyTags / Tag: TargetTag)
→ Branch
True → Multiply(BaseDamage × HolyMultiplier)→ ApplyHolyDamage(Target: As BP Enemy Base)
False → ApplyHolyDamage(Damage: BaseDamage、Target: As BP Enemy Base)
Has Tag ノードは、EnemyTags ピンからドラッグして検索すると出てきます。Tag 入力には変数 TargetTag を繋ぎます。ここを直接タグリテラルで指定してもよいのですが、変数にしておくと レベルに置いた聖水ごとに対象を変えられます (獣特効の聖水は Enemy.Beast に差し替えるだけです)。
ステップ5:レベルに置いて確認する。 BP_Skeleton / BP_Zombie / BP_Wolf を並べて配置し、BP_HolyWater をその中央に置きます。ApplyHolyDamage の中で Print String を使い、残りHPを表示させておくと確認しやすくなります(→ Print Stringで値を確認する)。
Playして聖水の範囲に敵が入ると、次の値が出るはずです。
| 敵 | 受けるダメージ | 残りHealth |
|---|---|---|
BP_Skeleton | 100.0(20 × 5) | 0.0 |
BP_Zombie | 100.0 | 0.0 |
BP_Wolf | 20.0 | 80.0 |
オオカミだけが80で残っていれば成功です。3体とも100ダメージなら Has Tag に繋いだタグを、3体とも20なら EnemyTags の設定を疑ってください。
ここからが本題です。 BP_EnemyBase の子として BP_Wraith を作り、Project Settingsで Enemy.Undead.Wraith を追加して EnemyTags に設定します。 BP_HolyWater を開かずに レベルへ置いてPlayすると、レイスは100ダメージを受けて倒れます。これがEnumとの決定的な違いです。
ポイントは2つです。
- 判定は親タグで書く:
Has Tagに渡すのはEnemy.UndeadであってEnemy.Undead.Skeletonではありません。「どこまで広く効かせたいか」の階層でタグを選ぶと、追加に強い形になります - タグはデータ、判定はロジック: 敵が持つタグはレベルやBlueprintの既定値(データ)、聖水が見るタグは変数(設定)です。 コードに種類名を埋め込まない ことで、拡張がデータ側の作業だけで済みます。Data Tableと組み合わせれば敵のパラメータごと外に出せます(→ Data Tableでゲームデータを管理する)
おまけ:先に知っておくと良いこと
Gameplay Tag Containerは実行中に足し引きできます。 状態管理に使う場合、毒を受けたら Add Gameplay Tag で Status.Debuff.Poison を足し、解除で Remove Gameplay Tag します。bIsPoisoned のようなbool変数を増やし続けるより、状態が1つの場所にまとまります。
タグの名前は「上から下へ絞り込む」順に並べます。 Skeleton.Enemy.Undead のように細かいものを先頭に置くと、階層でまとめる利点が消えます。 左が大きい分類、右へ行くほど具体 が原則です。
深くしすぎないことも大切です。 Item.Weapon.Melee.Sword.OneHanded.Iron.Rusty まで作ると、どの階層で判定すべきか自分でも分からなくなります。実際に「まとめて扱いたい単位」がある階層だけを作れば十分です。
タグを増やす前に、本当にタグが要るかを考えてください。 値が2つしかなく、増える見込みもないなら bool で十分です。Gameplay Tagが効くのは 分類が増える見込みがあり、かつ「まとめて扱いたい」ときだけ です。
大規模な例を見たいときはLyraが参考になります。 Epic公式のサンプル Lyra Sample Game は、タグをカテゴリ別のヘッダに整理してC++定義しています。ただし規模が大きいので、個人開発でそのまま真似する必要はありません。
まとめ
| Enum | Name(文字列) | Gameplay Tag | |
|---|---|---|---|
| 追加のしやすさ | 定義変更で全体に波及 | 自由 | 自由 |
| 綴り間違い | 起きない | 実行時まで気づけない | プルダウン選択なので起きない |
| まとめて判定 | 列挙するしかない | できない | 親タグで一発 |
- Gameplay Tagは
.で階層をつけた名札 。BlueprintだけでもC++なしで使える - 子タグは親タグに一致する 。この一方通行が「追加しても壊れない」の正体
- 追加は Project Settings から。実体は
Config/DefaultGameplayTags.iniのテキスト - コンテナには Has Tag / Has Any Tags / Has All Tags 、単体タグには Matches Tag
- 判定は 広く効かせたい階層のタグ で書く
タグで種類を整理できたら、次はその種類ごとの数値をデータ側へ出す番です。敵ごとのHPや報酬をまとめて管理する方法は Data Tableでゲームデータを管理する で、種類ごとの振る舞いを差し替える方法は Blueprint Interfaceの記事 で扱っています。
あなたのプロジェクトで、いま Switch on Enum がいちばん長く伸びているのはどのBlueprintでしょうか。