# Unreal - Tag与GameplayTag


### 1. Actor Tags：基础但脆弱的“老兵”

**Actor Tags** 是定义在 `AActor` 类中的一个简单字符串数组：
`TArray<FName> Tags;`

#### 特点：
*   **实现简单**：你可以直接在 Actor 的 Details 面板里手动输入任何字符串。
*   **扁平化结构**：它是完全平等的字符串列表，没有层级关系。
*   **低门槛**：不需要任何前置配置。

#### 致命弱点：
*   **拼写地狱（Typo-Prone）**：你在代码里检查 `"Stunned"`，但策划在编辑器里手抖打成了 `"Stuned"`。编译器不会报错，但你的逻辑会莫名其妙地失效。
*   **缺乏逻辑关联**：如果你想检查一个角色是否处于“任何负面状态”，你必须手动列出 `"Stunned"`, `"Frozen"`, `"Burned"`。你无法通过类似“所有的 Debuff”这样的母概念来查询。
*   **性能瓶颈**：在大规模查询时，字符串比较的效率远低于数值比较。

---

### 2. Gameplay Tags：结构化与高性能的“现代派”

**Gameplay Tags** 是随 GAS 系统一同发扬光大的高级标签系统。它不再是随手乱写的字符串，而是**需要在项目设置中注册的规范化数据**。

#### 特点：
*   **层级结构（Hierarchical）**：支持 `A.B.C` 的格式。例如 `State.Debuff.Stun`。
*   **高性能**：虽然我们在编辑器里看到的是文字，但其底层会被转换为唯一的 **32位整数 ID**。这意味着在执行“是否拥有该标签”的检查时，本质上是极快的整数比对。
*   **强类型安全**：你只能从预定义的列表中选择标签，彻底杜绝了拼写错误。
*   **容器化（Container）**：配套的 `FGameplayTagContainer` 支持强大的位运算，可以瞬间判断“包含全部”、“包含任意”或“不包含”。

---

### 3. 核心差异对决

| 特性         | Actor Tags (FName Tags) | Gameplay Tags                               |
| :----------- | :---------------------- | :------------------------------------------ |
| **底层数据** | `FName` (字符串)        | `int32` (整数 ID)                           |
| **结构形态** | 扁平数组 (Flat)         | **树状层级 (Hierarchical)**                 |
| **容错率**   | 极低 (拼写错误无提醒)   | **极高 (IDE/编辑器自动补全)**               |
| **查询性能** | 一般                    | **极快**                                    |
| **逻辑深度** | 仅支持精确匹配          | **支持父子包含关系（匹配 A 即可匹配 A.B）** |
| **管理方式** | 散落在各个 Actor 实例中 | **中心化管理 (Data Table 或 .ini)**         |

---

### 4. 为什么 GAS 选择了 Gameplay Tags？

GAS 的核心灵魂是 **“基于状态的逻辑切换”**。如果没有 Gameplay Tags，GAS 几乎无法工作。

#### A. 模糊匹配的威力
假设你的技能要求“目标不能处于任何 Debuff 状态”。
*   使用 **Actor Tags**：你需要检查目标是否不含标签 A、B、C...（如果以后新加了 D 状态，所有技能代码都要改）。
*   使用 **Gameplay Tags**：你只需要检查目标是否拥有 `State.Debuff`。无论子级是 `Stun` 还是新加的 `Sleep`，只要它属于 `State.Debuff` 的子树，系统就能自动识别。

#### B. 数据驱动的解耦
Gameplay Tags 允许策划在不触碰 C++ 代码的情况下，通过修改 GE（Gameplay Effect）里的标签组合，直接改变技能的互斥、中止和叠加逻辑。

#### C. 网络同步优化
由于 Gameplay Tags 内部是整数，它在网络传输时的开销远小于发送长字符串，这对于高频同步的多人对战游戏至关重要。

---

### 5. 什么时候该用哪种？

*   **使用 Actor Tags 的场景**：
    *   非常简单的原型开发。
    *   非游戏逻辑的简单标记（例如：标识场景中哪些物体是“可抓取的”）。
    *   由于历史原因残留的旧插件接口。

*   **使用 Gameplay Tags 的场景（推荐）**：
    *   **所有的战斗系统、技能系统、状态系统**。
    *   UI 数据的分类与筛选。
    *   复杂的交互逻辑（如：只有手持 `Item.Key.Blue` 的玩家才能打开 `Door.Blue`）。

---

### 结语

如果说 **Actor Tags** 是路边随处可见的便利贴，那么 **Gameplay Tags** 就是图书馆里的索引系统。

对于追求严谨、性能和可扩展性的虚幻开发者来说，**尽快抛弃 Actor Tags 并全面拥抱 Gameplay Tags**，是迈向高级架构师的必经之路。

---
*版权声明：本文为原创技术博客，转载请注明出处。*

