Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
中文简介正在准备中。当前显示原文说明。
Use when working with Unreal's Gameplay Ability System - when GAS is worth it, where the AbilitySystemComponent lives and how it is initialised on server and client, AttributeSets with correct clamping and replication, GameplayEffects and execution calculations as data, abilities with commit/end, gameplay tags, prediction, and testing.
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
GAS is Unreal's framework for abilities, attributes, buffs, cooldowns and costs, with network prediction built in. It pays off in games with many abilities and stacking effects, especially multiplayer ones; it is heavy machinery for a platformer with one jump. Most GAS bugs are setup bugs: the component initialised on one side only, clamping in the wrong callback, abilities that never end.
Core principle: Abilities are code, numbers are GameplayEffects (data), state is gameplay tags, and every attribute change goes through an effect so it replicates and predicts correctly.
| Owner of the ASC | Use for |
|---|---|
APlayerState | Player characters — attributes and effects survive pawn death and respawn |
The ACharacter itself | AI and simple pawns |
Replication mode: Full (single-player), Mixed (player-controlled, multiplayer), Minimal (AI in multiplayer).
// Server: when the controller possesses the pawn
void AHeroCharacter::PossessedBy(AController* NewController) {
Super::PossessedBy(NewController);
InitAbilitySystem();
}
// Client: when the PlayerState replicates
void AHeroCharacter::OnRep_PlayerState() {
Super::OnRep_PlayerState();
InitAbilitySystem();
}
void AHeroCharacter::InitAbilitySystem() {
auto* PS = GetPlayerState<AHeroPlayerState>();
if (!PS) return;
AbilitySystem = PS->GetAbilitySystemComponent();
AbilitySystem->InitAbilityActorInfo(PS, this); // owner = PlayerState, avatar = this pawn
if (HasAuthority()) GrantStartupAbilitiesAndEffects();
}
Missing the client-side InitAbilityActorInfo is the classic "works on the server, abilities do nothing on the client" bug. Implement IAbilitySystemInterface on the actors that own or carry the ASC.
UCLASS()
class UHealthSet : public UAttributeSet {
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health) FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(UHealthSet, Health)
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth) FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS(UHealthSet, MaxHealth)
UPROPERTY(BlueprintReadOnly) FGameplayAttributeData IncomingDamage; // meta attribute, server only
ATTRIBUTE_ACCESSORS(UHealthSet, IncomingDamage)
virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out) const override;
UFUNCTION() void OnRep_Health(const FGameplayAttributeData& Old) { GAMEPLAYATTRIBUTE_REPNOTIFY(UHealthSet, Health, Old); }
UFUNCTION() void OnRep_MaxHealth(const FGameplayAttributeData& Old) { GAMEPLAYATTRIBUTE_REPNOTIFY(UHealthSet, MaxHealth, Old); }
};
void UHealthSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) {
if (Data.EvaluatedData.Attribute == GetIncomingDamageAttribute()) {
const float Damage = GetIncomingDamage();
SetIncomingDamage(0.f);
SetHealth(FMath::Clamp(GetHealth() - Damage, 0.f, GetMaxHealth())); // the real clamp
}
}
ATTRIBUTE_ACCESSORS is the project's helper macro wrapping the GAMEPLAYATTRIBUTE_* getters/setters/initter — use the one the project defines.PreAttributeChange only clamps the value being queried (current value from modifiers); it does not permanently change the base value. Clamp for real in PostGameplayEffectExecute.IncomingDamage) so armour, shields and death are handled in one place.DOREPLIFETIME_CONDITION_NOTIFY(UHealthSet, Health, COND_None, REPNOTIFY_Always).SetByCaller (tagged values set by the ability), Modifier Magnitude Calculations, or an Execution Calculation for formulas that read several attributes (damage vs armour).CommitAbility.void UGA_Fireball::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* Info,
const FGameplayAbilityActivationInfo Activation, const FGameplayEventData* Trigger) {
if (!CommitAbility(Handle, Info, Activation)) { // pays cost and starts cooldown, or fails
EndAbility(Handle, Info, Activation, /*bReplicate*/ true, /*bWasCancelled*/ true);
return;
}
auto* Task = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, NAME_None, CastMontage);
Task->OnCompleted.AddDynamic(this, &UGA_Fireball::OnCastFinished);
Task->OnCancelled.AddDynamic(this, &UGA_Fireball::OnCastCancelled);
Task->ReadyForActivation();
}
EndAbility — including failure and cancellation — or the ability stays active forever and blocks itself.InstancedPerActor unless there is a reason otherwise; net execution LocalPredicted for player abilities.HasAuthority(&ActivationInfo)); the client predicts cosmetics.State.Dead, State.Stunned, Ability.Skill.Fireball, Cooldown.Skill.Fireball.ActivationBlockedTags (State.Stunned), CancelAbilitiesWithTag, ActivationOwnedTags.UE_DEFINE_GAMEPLAY_TAG) or in DefaultGameplayTags.ini — the way the project already does; no tag strings typed ad hoc in code.FGameplayEffectSpec, and asserts attribute values (unreal-automation-testing).InitAbilityActorInfo called on the server only.PreAttributeChange.EndAbility on some path.Full replication mode on hundreds of AI.还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
中文简介正在准备中。当前显示原文说明。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
中文简介正在准备中。当前显示原文说明。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
中文简介正在准备中。当前显示原文说明。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
中文简介正在准备中。当前显示原文说明。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
中文简介正在准备中。当前显示原文说明。
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
中文简介正在准备中。当前显示原文说明。