关于 ue-gameplay-abilities
面向 UE 5.8 Gameplay Ability System 开发者的 Skill,介绍能力、效果、属性、任务、标签、复制与 Gameplay Cues,并包含初始化和配置模式。
主要功能
- 01Ability System Component 设置
- 02能力激活与策略
- 03能力任务和事件等待
- 04Gameplay 效果与属性
- 05标签、复制与 Cues
适用场景
- 01实现带消耗或冷却的能力
- 02等待动画或 Gameplay 事件
- 03应用伤害或限时增益
- 04配置 ASC 所有权与复制
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ quodsoler/ unreal-engine-skills --skill ue-gameplay-abilities安装后在 Claude Code 中输入/ue-gameplay-abilities确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ability-task-reference.mdgameplay-effect-reference.mdgas-setup-patterns.md详细介绍
UE Gameplay Ability System
目标引擎:UE 5.8。以下 API 已根据 5.8 头文件验证;旧形式列在“已弃用 — 请勿使用”下。
GAS 随 GameplayAbilities 插件一起提供(Engine/Plugins/Runtime/GameplayAbilities),已可用于生产环境,并非 Experimental。在 .uproject 中启用该插件,然后将 "GameplayAbilities"、"GameplayTags" 和 "GameplayTasks" 添加到模块 Build.cs 的 PublicDependencyModuleNames 中。本指南涵盖 UAbilitySystemComponent、UGameplayAbility、UGameplayEffect、UAttributeSet、UAbilityTask 和 Gameplay Cues。
上下文
如果 .agents/ue-project-context.md 文件存在,请阅读它(模块名称、约定、已启用的插件、GAS/网络设置)。如果该文件不存在,也请继续。
根据请求和代码库确定相关部分。只有当两种合理的理解会导致不同代码时,才询问。
| 请求涉及…… | 请参阅 |
|---|---|
| ASC 所属位置、初始化顺序、重生、复制模式 | ASC 所属关系与初始化 |
| 编写能力、激活、消耗、冷却时间、策略 | Gameplay Abilities |
| 等待蒙太奇、事件、目标选择、计时器、标签查询 | 能力任务 |
| 伤害、增益、堆叠、执行、免疫、GE 组件 | Gameplay Effects |
| 生命值/法力值浮点数、限制范围、属性复制 | 属性集 |
| 阻止、授予或取消能力的标签;宽松标签 | GAS 中的标签 |
| 粒子、声音、命中效果、Cue 通知类 | Gameplay Cues |
| Cue 扫描路径、全局曲线表、项目配置 | 项目设置 |
GAS 架构
| 支柱 | 类 | 头文件 | 用途 |
|---|---|---|---|
| 组件 | UAbilitySystemComponent | AbilitySystemComponent.h | 管理能力、效果、属性和标签 |
| 能力 | UGameplayAbility | Abilities/GameplayAbility.h | 激活时发生的行为 |
| 效果 | UGameplayEffect | GameplayEffect.h | 由数据驱动的属性修改 |
| 属性 | UAttributeSet | AttributeSet.h | 复制的 FGameplayAttributeData 属性 |
| 任务 | UAbilityTask | Abilities/Tasks/AbilityTask.h | 能力内部的延迟步骤 |
Gameplay 标签贯穿所有这些部分,用作要求、授予项和阻止条件。
ASC 所属关系与初始化
| 所属对象 | 适用场景 | 备注 |
|---|---|---|
APlayerState | 联网的玩家角色 | ASC 在 Pawn 死亡后仍然存在;使用 Mixed 复制模式 |
APawn / ACharacter | AI、单机游戏 | 最简单;AI 使用 Minimal,如果 Pawn 所属的 ASC 需要向所有客户端提供完整数据,则使用 Full |
每个拥有或公开 ASC 的 Actor 都要实现 IAbilitySystemInterface:
// MyCharacter.h
#pragma once
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "MyCharacter.generated.h"
class UAbilitySystemComponent;
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AMyCharacter();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GAS")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
};
// MyCharacter.cpp
#include "MyCharacter.h"
#include "AbilitySystemComponent.h"
AMyCharacter::AMyCharacter()
{
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
}
UAbilitySystemComponent* AMyCharacter::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}
InitAbilityActorInfo(OwnerActor, AvatarActor) 必须在服务器和客户端上都运行。对于 Pawn 所属的 ASC,在 BeginPlay 中以 (this, this) 调用。对于 PlayerState 所属的 ASC,在服务器上的 PossessedBy 和客户端上的 OnRep_PlayerState 中以 (PlayerState, Character) 调用。完整的双路径代码、重生处理和 AI 变体,请参阅 gas-setup-patterns.md。
EGameplayEffectReplicationMode | 对模拟代理的影响 |
|---|---|
Minimal | 不复制 GE;仅提供最少的标签/Cue 数据。适用于 AI 和非玩家 Actor |
Mixed | 向所属连接发送完整 GE,向其他所有连接发送最少数据。适用于玩家角色 |
Full | 将每个 GE 复制给每个客户端 |
Mixed 会向拥有 ASC 所属 Actor 的连接发送完整 GE 数据(GameplayEffect.cpp:5240),因此适用于 PlayerState 所属的 ASC,也适用于 PlayerController 控制 Pawn 后的 Pawn 所属 ASC。选择 Full 而非 Mixed 是带宽方面的取舍,而非正确性问题。Minimal 不适用于玩家所属的 ASC(AbilitySystemComponent.h:83)。有关每种模式的网络带宽开销,请参阅 ue-networking-replication。
Gameplay 能力
// MyFireballAbility.h
#pragma once
#include "Abilities/GameplayAbility.h"
#include "MyFireballAbility.generated.h"
class UGameplayEffect;
UCLASS()
class MYGAME_API UMyFireballAbility : public UGameplayAbility
{
GENERATED_BODY()
public:
UMyFireballAbility();
virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayTagContainer* SourceTags = nullptr,
const FGameplayTagContainer* TargetTags = nullptr,
OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const override;
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData) override;
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateEndAbility, bool bWasCancelled) override;
virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateCancelAbility) override;
protected:
UPROPERTY(EditDefaultsOnly, Category = "GAS")
TSubclassOf<UGameplayEffect> DamageEffect;
};
构造函数设置策略和能力自身的标签:
// MyFireballAbility.cpp
#include "MyFireballAbility.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemComponent.h"
UMyFireballAbility::UMyFireballAbility()
{
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
NetSecurityPolicy = EGameplayAbilityNetSecurityPolicy::ClientOrServer;
FGameplayTagContainer Tags;
Tags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Skill.Fireball")));
SetAssetTags(Tags);
ActivationOwnedTags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Active.Casting")));
ActivationBlockedTags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("State.Stunned")));
CancelAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Active.Melee")));
}
SetAssetTags 只能在构造函数中调用;使用 GetAssetTags() 读取标签。
| 枚举 | 值 | 用途 |
|---|---|---|
EGameplayAbilityInstancingPolicy | InstancedPerActor, InstancedPerExecution | InstancedPerActor 是默认选择;多个实例可能同时运行时使用 InstancedPerExecution |
EGameplayAbilityNetExecutionPolicy | LocalPredicted, LocalOnly, ServerInitiated, ServerOnly | 响应迅速的玩家能力使用 LocalPredicted |
EGameplayAbilityNetSecurityPolicy | ClientOrServer, ServerOnlyExecution, ServerOnlyTermination, ServerOnly | 拒绝应由服务器控制的客户端请求 |
void UMyFireballAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
// CommitAbility applies cost and cooldown; it fails if either cannot be paid.
if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
{
EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
return;
}
const FGameplayEffectSpecHandle Spec =
MakeOutgoingGameplayEffectSpec(DamageEffect, GetAbilityLevel());
const FGameplayAbilityTargetDataHandle TargetData =
UAbilitySystemBlueprintLibrary::AbilityTargetDataFromActor(ActorInfo->AvatarActor.Get());
ApplyGameplayEffectSpecToTarget(Handle, ActorInfo, ActivationInfo, Spec, TargetData);
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
}
如果两部分必须在不同时间发生,则拆分提交:CommitAbilityCost(Handle, ActorInfo, ActivationInfo) 和 CommitAbilityCooldown(Handle, ActorInfo, ActivationInfo, ForceCooldown)——注意,冷却时间重载会额外接收 const bool ForceCooldown。
在实例化的能力中,GetAbilitySystemComponentFromActorInfo_Ensured() 会返回 ASC;如果 Actor 信息尚未设置,它会记录 ensure,而不是导致崩溃。
从服务器授予并激活能力:
const FGameplayAbilitySpecHandle Handle =
ASC->GiveAbility(FGameplayAbilitySpec(UMyFireballAbility::StaticClass(), 1));
ASC->TryActivateAbility(Handle);
ASC->TryActivateAbilityByClass(UMyFireballAbility::StaticClass());
ASC->TryActivateAbilitiesByTag(
FGameplayTagContainer(FGameplayTag::RequestGameplayTag(TEXT("Ability.Skill.Fireball"))));
ASC->ClearAbility(Handle);
能力任务
能力任务可让能力跨越多个帧运行。流程始终是:静态工厂 → 绑定委托 → ReadyForActivation()(继承自 UGameplayTask)。任务委托是动态委托,因此每个处理函数都需要 UFUNCTION():
// In the ability's header:
UFUNCTION()
void HandleMontageCompleted();
UFUNCTION()
void HandleMontageInterrupted();
#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
UAbilityTask_PlayMontageAndWait* Task =
UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
this, NAME_None, AttackMontage, 1.f);
Task->OnCompleted.AddDynamic(this, &UMyFireballAbility::HandleMontageCompleted);
Task->OnInterrupted.AddDynamic(this, &UMyFireballAbility::HandleMontageInterrupted);
Task->ReadyForActivation();
| 任务 | 等待内容 |
|---|---|
UAbilityTask_PlayMontageAndWait | UAnimMontage 播放完毕、混出、中断或取消 |
UAbilityTask_PlayAnimAndWait | 播放到槽位中的原始 UAnimSequence,用于关联动画层 |
UAbilityTask_WaitGameplayEvent | 发送给 ASC 的游戏性事件标签(动画通知、命中注册) |
UAbilityTask_WaitDelay | 固定秒数 |
UAbilityTask_WaitTargetData | AGameplayAbilityTargetActor 确认目标 |
UAbilityTask_WaitAttributeChange / ...ChangeThreshold | 属性发生变化或跨越比较阈值 |
UAbilityTask_WaitGameplayTagQuery | 目标的标签满足或不满足 FGameplayTagQuery |
UAbilityTask_WaitGameplayTagCountChanged | ASC 上某个标签的计数发生变化 |
UAbilityTask_WaitGameplayEffectApplied_Self / _Target | 匹配标签要求的 GE(或通过 _Query 工厂使用 FGameplayTagQuery) |
工厂的完整签名、委托名称、自定义任务模板和任务注意事项,请参阅 ability-task-reference.md。
游戏性效果
EGameplayEffectDurationType | 行为 |
|---|---|
Instant | 对基础值执行一次;触发 PostGameplayEffectExecute |
HasDuration | 在 DurationMagnitude 秒内聚合到当前值 |
Infinite | 持续聚合,直到显式移除 |
const FGameplayEffectContextHandle Ctx = ASC->MakeEffectContext();
const FGameplayEffectSpecHandle Spec =
ASC->MakeOutgoingSpec(UMyDamageEffect::StaticClass(), Level, Ctx);
Spec.Data->SetSetByCallerMagnitude(
FGameplayTag::RequestGameplayTag(TEXT("SetByCaller.Damage")), 75.f);
ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get());
ASC->ApplyGameplayEffectSpecToTarget(*Spec.Data.Get(), TargetASC);
ASC->RemoveActiveGameplayEffect(ActiveHandle);
ASC->RemoveActiveGameplayEffectBySourceEffect(UMyDamageEffect::StaticClass(), nullptr);
修饰符运算位于 EGameplayModOp 中(这是一个带命名空间的枚举,因此值的类型为 TEnumAsByte<EGameplayModOp::Type>)。聚合公式为
((BaseValue + AddBase) * MultiplyAdditive / DivideAdditive * MultiplyCompound) + AddFinal。
| 值 | 含义 |
|---|---|
AddBase | 在其他操作之前加到基础值上 |
MultiplyAdditive | 将乘数相加,然后与当前结果相乘 |
DivideAdditive | 将除数相加,然后用当前结果除以该值 |
MultiplyCompound | 与当前结果相乘,并与其他复合乘数连乘 |
AddFinal | 所有乘法完成后再加上 |
Override | 替换计算出的值 |
过去作为 UGameplayEffect 单体属性的行为,现在由 GameplayEffectComponents/ 下的 UGameplayEffectComponent 子类实现。有关堆叠、幅度计算、UGameplayEffectExecutionCalculation、周期性效果、免疫、查询、生命周期委托和完整的组件列表,请参阅 gameplay-effect-reference.md。
属性集
// MyHealthSet.h
#pragma once
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "MyHealthSet.generated.h"
UCLASS()
class MYGAME_API UMyHealthSet : public UAttributeSet
{
GENERATED_BODY()
public:
UMyHealthSet();
virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "Health")
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS_BASIC(UMyHealthSet, Health)
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category = "Health")
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS_BASIC(UMyHealthSet, MaxHealth)
protected:
UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldHealth);
UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth);
};
ATTRIBUTE_ACCESSORS_BASIC 会生成 GetHealthAttribute()、GetHealth()、SetHealth() 和 InitHealth()。需要额外访问器的项目可以定义自己的宏,通过 GAMEPLAYATTRIBUTE_PROPERTY_GETTER、GAMEPLAYATTRIBUTE_VALUE_GETTER、GAMEPLAYATTRIBUTE_VALUE_SETTER 和 GAMEPLAYATTRIBUTE_VALUE_INITTER 链接调用。
每个 OnRep_ 函数体只包含一处 GAMEPLAYATTRIBUTE_REPNOTIFY(UMyHealthSet, Health, OldHealth) 调用,并且每个属性都需要一行 DOREPLIFETIME_CONDITION_NOTIFY(UMyHealthSet, Health, COND_None, REPNOTIFY_Always)。带钳制逻辑的完整 .cpp 文件见 gas-setup-patterns.md。
| 钩子 | 触发时机 | 用途 |
|---|---|---|
PreAttributeChange | 每次重新计算当前值时 | 仅钳制当前值 |
PreAttributeBaseChange | 写入基础值之前(const) | 钳制基础值 |
PostGameplayEffectExecute | 即时 GE 写入基础值后,或周期性 GE 的一个周期写入基础值后 | 死亡、受击反应、游戏事件 |
PostAttributeChange | 当前值发生变化后 | 响应派生状态 |
注册和读取:
// Constructor of the ASC owner — the ASC finds subobject attribute sets automatically:
HealthSet = CreateDefaultSubobject<UMyHealthSet>(TEXT("HealthSet"));
// Runtime, authority only:
UMyHealthSet* NewSet = NewObject<UMyHealthSet>(this);
ASC->AddSpawnedAttribute(NewSet);
const float CurrentHealth = ASC->GetNumericAttribute(UMyHealthSet::GetHealthAttribute());
一个 ASC 可以承载多个 UAttributeSet 子类,但每个类只能有一个实例。
GAS 中的标签
标签定义(原生标签宏、.ini 标签源)、容器匹配和 FGameplayTagQuery 语义属于 ue-gameplay-tags-messaging。GAS 特有的内容如下:
// On the ability CDO (constructor): tags granted while the ability runs, and the gates.
ActivationOwnedTags.AddTag(CastingTag);
ActivationRequiredTags.AddTag(WeaponEquippedTag);
ActivationBlockedTags.AddTag(StunnedTag);
BlockAbilitiesWithTag.AddTag(MeleeTag);
CancelAbilitiesWithTag.AddTag(ChannelTag);
// On the ASC: query and react.
ASC->HasMatchingGameplayTag(StunnedTag);
const FGameplayTagContainer& Owned = ASC->GetOwnedGameplayTags();
ASC->RegisterGameplayTagEvent(StunnedTag, EGameplayTagEventType::NewOrRemoved)
.AddUObject(this, &AMyCharacter::HandleStunnedTagChanged);
回调声明为 void HandleStunnedTagChanged(const FGameplayTag Tag, int32 NewCount);,无需 UFUNCTION() —— 标签事件是普通的多播委托。
松散标签直接设置,而不是通过 GE 设置。第三个参数决定标签的复制方式:
ASC->AddLooseGameplayTag(StunnedTag); // local only
ASC->AddLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::TagOnly); // tag to all
ASC->AddLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::CountToOwner);// + count to owner
ASC->RemoveLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::TagOnly);
ASC->SetLooseGameplayTagCount(BuffedTag, 3, EGameplayTagReplicationState::TagAndCountToAll);
EGameplayTagReplicationState 的取值包括:None、SimulatedTagOnly、TagOnly、CountToOwner、TagAndCountToAll。除 None 外,所有取值都必须在服务器上添加。
Gameplay Cues
Cue 仅用于外观效果。标签前缀为 GameplayCue.;GE 可通过其 GameplayCues 数组触发 Cue,也可以由代码直接触发:
ASC->ExecuteGameplayCue(HitCueTag, ASC->MakeEffectContext()); // one-shot
ASC->AddGameplayCue(BuffCueTag); // persistent
ASC->RemoveGameplayCue(BuffCueTag);
const bool bActive = ASC->IsGameplayCueActive(BuffCueTag);
| 类 | 基类 | 重载项 | 用途 |
|---|---|---|---|
UGameplayCueNotify_Static | UObject | OnExecute_Implementation | 不生成 Actor 的瞬时 Cue |
UGameplayCueNotify_Burst | UGameplayCueNotify_Static | 数据驱动的瞬时效果 | 一次性粒子效果/声音,无需编写代码 |
UGameplayCueNotify_HitImpact | UGameplayCueNotify_Static | 数据驱动的冲击效果 | 按表面类型区分的冲击效果 |
AGameplayCueNotify_Actor | AActor | OnActive_/WhileActive_/OnRemove_Implementation | 需要 Actor 的持续 Cue |
AGameplayCueNotify_BurstLatent | AGameplayCueNotify_Actor | 数据驱动的瞬时效果 | 必须生成 Actor 的瞬时 Cue |
AGameplayCueNotify_Looping | AGameplayCueNotify_Actor | 数据驱动的循环效果 | 循环光环和引导效果 |
// MyHitCue.h
#pragma once
#include "GameplayCueNotify_Static.h"
#include "MyHitCue.generated.h"
UCLASS()
class MYGAME_API UMyHitCue : public UGameplayCueNotify_Static
{
GENERATED_BODY()
public:
virtual bool OnExecute_Implementation(AActor* MyTarget,
const FGameplayCueParameters& Parameters) const override;
};
UGameplayCueManager 会在项目设置中配置的扫描路径下发现 Cue 资源。
项目设置
GAS 配置由 UDeveloperSettings 类提供:UGameplayAbilitiesDeveloperSettings(项目设置 → Gameplay Abilities)。使用 GetDefault<UGameplayAbilitiesDeveloperSettings>() 读取。值得注意的字段包括:GameplayCueNotifyPaths、ReplicateActivationOwnedTags、bAllowGameplayModEvaluationChannels,以及全局曲线/属性表。运行时辅助函数仍由 UAbilitySystemGlobals 提供(GetGameplayCueNotifyPaths()、AddGameplayCueNotifyPath()、GetAttributeSetInitter())。
已弃用 — 请勿使用
| 请勿发出 | 在 5.8 中使用 | 来源 |
|---|---|---|
AGameplayCueNotify_Static | UGameplayCueNotify_Static(一个 UObject) | 此类从未存在;GameplayCueNotify_Static.h:19 |
EGameplayModOp::Multiplicative | EGameplayModOp::MultiplyAdditive(旧版别名拼写为 Multiplicitive) | GameplayEffectTypes.h:112-148 |
EGameplayModOp::Additive / Division | AddBase / DivideAdditive | 隐藏的向后兼容别名,GameplayEffectTypes.h:141-143 |
EGameplayAbilityInstancingPolicy::NonInstanced | InstancedPerActor | Abilities/GameplayAbilityTypes.h:46 中的 UE_DEPRECATED_FORGAME(5.5) |
UGameplayAbility::AbilityTags | GetAssetTags() / SetAssetTags() | Abilities/GameplayAbility.h:474 中的 UE_DEPRECATED_FORGAME(5.5) |
GetAbilitySystemComponentFromActorInfo_Checked() | GetAbilitySystemComponentFromActorInfo_Ensured() | Abilities/GameplayAbility.h:168 中的 UE_DEPRECATED(5.5) |
对 Actor 赋值 NetUpdateFrequency | SetNetUpdateFrequency(100.f) | GameFramework/Actor.h:903 中的 UE_DEPRECATED(5.5) |
UGameplayEffect::StackingType(公开读取) | GetStackingType() | GameplayEffect.h:2407 中的 UE_DEPRECATED(5.7) |
UGameplayEffect::GrantedApplicationImmunityTags | UImmunityGameplayEffectComponent | GameplayEffect.h:2379 中的 UE_DEPRECATED(5.3) |
AddReplicatedLooseGameplayTag | AddLooseGameplayTag(Tag, Count, EGameplayTagReplicationState::CountToOwner)(弃用消息中的替代项;如果客户端不需要计数,则使用 TagOnly) | 函数已移除(5.8 中没有声明);其底层的 ReplicatedLooseTags 成员在 AbilitySystemComponent.h:1941 中标记为 UE_DEPRECATED(5.7) |
FGameplayAbilitySpec::DynamicAbilityTags | GetDynamicSpecSourceTags() | GameplayAbilitySpec.h:242 中的 UE_DEPRECATED(5.5) |
UAbilitySystemBlueprintLibrary::MakeSpecHandle | MakeSpecHandleByClass | AbilitySystemBlueprintLibrary.h:249 中的 UE_DEPRECATED(5.5) |
UAbilitySystemGlobals 配置成员 | GetDefault<UGameplayAbilitiesDeveloperSettings>() | AbilitySystemGlobals.h 中均标记为 UE_DEPRECATED(5.5) |
FGameplayEffectSpec::GetModifierMagnitude(ModifierIdx, bFactorInStackCount) | GetModifierMagnitude(int32 ModifierIdx) | GameplayEffect.h:1153 中的 UE_DEPRECATED(5.6) |
FActiveGameplayEffectHandle(int32)、ResetGlobalHandleMap()、RemoveFromGlobalMap() | FActiveGameplayEffectHandle::GenerateNewHandle() 或 GetInstantExecutedHandle();全局映射已移除 | ActiveGameplayEffectHandle.h:30,66,69 中的 UE_DEPRECATED(5.8) |
常见错误
**仅在 Pawn 上实现 IAbilitySystemInterface:**当 ASC 位于 PlayerState 上时,PlayerState 也必须实现该接口,否则 UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent 在获取所有者时会失败。
**只在服务器上调用 InitAbilityActorInfo:**客户端也需要调用。服务器端路径是 PossessedBy,客户端路径是 OnRep_PlayerState。如果不在客户端调用,属性变化委托永远不会在所属客户端触发。
**在初始化前应用 GE:**在运行 InitAbilityActorInfo 前授予能力或应用效果,会导致 ASC 缺少 Actor 信息,且属性集未注册。
在错误的钩子中进行钳制:PreAttributeChange 每次聚合器重新计算时都会触发,因此只能钳制 NewValue。死亡、受击反应和游戏事件应放在 PostGameplayEffectExecute 中处理;它只会在执行时运行(即时 GE 和周期性 Tick)。
**忘记调用 CommitAbility:**能力会运行,但不会支付消耗,也不会开始冷却。
误以为松散标签会复制:AddLooseGameplayTag(Tag) 默认使用 EGameplayTagReplicationState::None。从服务器传入 TagOnly 或 CountToOwner,或者通过 GE 授予标签。
**堆叠数悄然达到上限:**超出 GetStackLimitCount() 的应用会被拒绝,且不会报错。在假定堆叠成功前,先检查 GetCurrentStackCount(Handle)。
**在没有权限检查的情况下于 BeginPlay 中应用启动效果:**后续加入的玩家会再次应用这些效果。使用 HasAuthority() 为每次 GiveAbility 和启动 GE 调用添加权限门控。
**AI 没有 PlayerState:**将 ASC 放在 AI 角色上,调用 InitAbilityActorInfo(this, this) 并设置 Minimal 复制模式。
相关技能
ue-gameplay-tags-messaging— 标签定义(原生标签宏、ini 标签源)、容器、FGameplayTagQuery和游戏消息传递ue-networking-replication—DOREPLIFETIME变体、RPC、预测键、推送模型ue-animation-system— 动画能力任务驱动的蒙太奇资源、通知和插槽ue-character-movement— 根运动能力任务操控的移动模式ue-cpp-foundations—UPROPERTY/UFUNCTION说明符、委托、TSubclassOf、子系统ue-data-assets-tables— 属性初始化和FScalableFloat所依赖的UCurveTable和UDataTable资源ue-state-trees— 从 State Tree 任务运行能力ue-actor-component-architecture— 组件创建、子对象注册、子对象复制ue-gameplay-framework— PlayerState 和 Pawn 生命周期,以及不使用 GAS 的伤害处理(TakeDamage、UDamageType)ue-input-system— 绑定到能力输入 ID 的 Enhanced Input 动作ue-game-features— 从游戏功能插件授予能力和属性集ue-niagara-effects— Niagara 系统、用户参数、数据接口和数据通道ue-ui-umg-slate— UMG 控件、Slate、Common UI 和 MVVM