虚幻GAS底层原理解剖四 (TAG)


前言

深入 GAS(Gameplay Ability System)中的 Tag System 实现原理,这是 GAS 中一个非常精巧且强大的模块,支撑了:

  1. 技能激活条件
  2. 效果(GE)应用与否
  3. 角色状态判断(如“眩晕”、“隐身”)
  4. 整个系统的“规则引擎”和“语义判定”

一、Tag System 是什么?

GameplayTag 是一种 轻量级语义标记系统,其本质是用于:
表达角色、技能、效果、属性等的语义状态和行为约束。

类似状态机中的“状态标识”或者 ECS 中的“标签组件”。
例如:

Tag:   Status.Stunned       ← 表示眩晕
Tag:   Ability.BlockJump    ← 表示禁止跳跃
Tag:   Skill.Fireball       ← 表示火球技能
Tag:   Relationship.Enemy   ← 表示敌人单位

它们可以被:

  1. GE 授予/移除
  2. GA 监听/过滤
  3. AttributeSet 逻辑判断
  4. 网络同步/自动触发回调

二、核心结构组成

类名作用
FGameplayTag单个标签结构,底层是 FName
FGameplayTagContainer标签容器,可包含多个标签
UGameplayTagsManager全局管理器,构建标签层级和注册表
GameplayTag.ini标签配置文件,集中定义标签结构

三、标签的底层原理

  1. FGameplayTag
    这是标签的最小单元,本质是个 FName,但支持层级结构:
FGameplayTag StunTag = FGameplayTag::RequestGameplayTag("Status.Stunned");

层级结构以 . 分隔,例如:

Status
├── Status.Stunned
├── Status.Rooted
Ability
├── Ability.Magic
│   └── Ability.Magic.Fireball

支持“包含关系”判断:

StunTag.MatchesTag("Status")true
  1. FGameplayTagContainer
    容器类,表示“拥有的一组标签”:
FGameplayTagContainer Tags;
Tags.AddTag(FGameplayTag::RequestGameplayTag("Status.Stunned"));
可以用于:
判断是否包含某个标签或子标签
添加/移除标签
与其他容器做交集、并集等运算

四、标签系统的运行机制

GAS 中使用 Tag 的方式主要分为以下几类:

  1. 技能(GA)激活条件控制
AbilityTags: Ability.Fireball

ActivationBlockedTags: Status.Stunned
ActivationRequiredTags: State.CombatReady

激活前 GAS 会做自动检查:


if (OwnerHasTag(Status.Stunned)) {
    BlockActivation();
}
  1. 效果(GE)的条件过滤
GrantedTags: Status.Stunned         // 被应用时添加这个标签
OngoingTagRequirements:
    Required: Target.IsAlive
    Blocked: Target.HasShield
  1. 技能触发、监听和响应
    使用 WaitGameplayEvent 监听具有某标签的 GameplayEvent:
WaitGameplayEvent(EventTag = "Event.OnHit")
  1. 网络同步与事件广播
    GAS 会自动在网络上传输 TagContainer 变化,比如一个 GE 添加了 Status.Stunned,所有客户端都知道它被“眩晕”了。

五、Tag 系统与其他模块协同逻辑

模块使用方式
Ability(GA)控制是否能激活、是否中断
Effect(GE)控制能否应用、应用时授予标签
AttributeSet用来判定当前状态,比如不能回血
ASC保持一个 OwnedTags,动态更新角色状态

示例:火球技能不能在“沉默”状态下释放

AbilityTags = Ability.Magic.Fireball
ActivationBlockedTags = Status.Silenced

当角色被施加了 GE:Status.Silenced,该 GA 自动不能激活。

六、如何维护和组织标签:GameplayTags.ini

推荐统一维护所有标签,在 DefaultGameplayTags.ini 文件中注册:

[GameplayTags]
+GameplayTags=Ability.Magic.Fireball
+GameplayTags=Status.Stunned
+GameplayTags=Status.Silenced
+GameplayTags=Target.Friendly
+GameplayTags=Target.Enemy

优点:

  1. 自动提示 / 蓝图可选
  2. 防止拼写错误
  3. 支持导出层级树(调试友好)

七、底层调用逻辑示意(源码)

bool FGameplayTagContainer::HasTag(FGameplayTag TagToCheck, bool bExactMatch) const
{
    for (const FGameplayTag& Tag : GameplayTags)
    {
        if (Tag.MatchesTag(TagToCheck)) return true;
    }
    return false;
}
bool FGameplayTag::MatchesTag(const FGameplayTag& OtherTag) const
{
    return OtherTag == ThisTag || OtherTag.IsParentOf(ThisTag);
}

GAS 利用层级结构快速做匹配判断。

八、调试和可视化技巧

  1. Gameplay Debugger GDT(按 ~ 打开)
    显示当前角色所有 Active Tags

  2. ASC 的 GetOwnedGameplayTags()
    随时可打印当前标签状态

  3. 蓝图中可用 “Has Matching Gameplay Tag”、“Add Gameplay Tag” 节点操作

九、使用规范建议

场景推荐做法
表示状态Status.xxx(如 Status.Stunned)
分类技能Ability.Class.Type(如 Ability.Magic.Fireball)
表示阻断Block.Action(如 Block.Jump)
表示目标类型Target.Enemy / Target.Self
表示 BUFF、DEBUFFEffect.Buff.SpeedUp / Effect.Debuff.Slow

总结:Tag 是 GAS 的“布尔变量 + 规则引擎”

不要写 if(状态==1),而是:
通过标签系统进行统一的语义控制、判定与过滤。
模块使用 Tag 的方式
GA激活限制、冷却中断、触发事件
GE应用判断、附加状态标签
ASC状态维护、网络同步
UI/逻辑状态显示、行为约束
### 虚幻引擎中的GAS(Gameplay Ability System) #### GAS的核心功能 Gameplay Ability System (GAS)虚幻引擎的一个内置插件,提供了强大的框架来实现角色技能、属性系统以及状态效果等功能。它支持复杂的数值计算、能力消耗与冷却机制,并集成了网络同步和预测功能[^3]。 #### 插件激活 要在项目中使用 GAS,需先在插件管理器中启用该插件。一旦启用,可以通过 `AbilitySystemComponent` 来管理和执行各种能力和属性操作。 #### 主要组成部分 1. **Abilities(能力)** Abilities 定义了游戏中可触发的行为或动作,例如攻击、施法或其他交互行为。它们通常绑定到特定输入事件并具有自己的逻辑脚本。每个 Ability 可以设置资源成本(如生命值或能量)、持续时间及冷却周期。 2. **Attributes(属性)** Attributes 表示实体的基础数据项,比如健康度、耐力或者力量等级等。这些动态变化的数据由 `AttributeSet` 类型定义并通过 `AbilitySystemComponent` 进行更新维护。 3. **Effects(效果)** Effects 用于描述当某个条件满足时所发生的变化,可能涉及修改目标单位的一系列参数或是附加特殊标记(Tag)。常见的例子有伤害加成、减速惩罚等等。 4. **Gameplay Tags 和 Gameplay Events** - **Gameplay Tags**: 提供了一种灵活的方式来分类和检索游戏内的元素。几乎所有的核心结构都支持关联标签以便于查询匹配。 - **Gameplay Events**: 允许广播自定义消息给监听者列表从而驱动复杂互动链路的发生发展过程。 5. **Network Replication & Prediction** 鉴于多人在线环境下的需求考量,GAS 设计之初就充分考虑到了跨客户端间一致性保障的重要性,因此包含了完备可靠的网路传输解决方案. #### 示例代码展示如何创建简单的Skill System基于GAS: ```cpp // MyCharacter.h UCLASS() class MYPROJECT_API AMyCharacter : public ACharacter { GENERATED_BODY() public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") UAbilitySystemComponent* AbilitySystemComp; protected: virtual void BeginPlay() override; }; // MyCharacter.cpp #include "MyCharacter.h" #include "AbilitySystemBlueprintLibrary.h" AMyCharacter::AMyCharacter(const FObjectInitializer& ObjectInitializer) { AbilitySystemComp = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemComp")); } void AMyCharacter::BeginPlay() { Super::BeginPlay(); if(AbilitySystemComp && HasAuthority()) { // Grant abilities on server side only. FGameplayAbilitySpecDef SpecDef; SpecDef.Ability = StaticClass()->FindFunctionByName(FName(TEXT("ExecuteBasicAttack"))); SpecDef.InputID = EInputAction::IA_BasicAttack; // Assuming you have this enum defined elsewhere const TArray<FGameplayEffectContextHandle> ContextHandles; AbilitySystemComp->GiveAbility(SpecDef); // Initialize default attributes here... } } ``` 上述片段展示了怎样在一个继承自ACharacter类的新角色身上添加基本战斗技巧的能力授予方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值