添加 claude code game studios 到项目
This commit is contained in:
386
docs/engine-reference/unreal/plugins/gameplay-ability-system.md
Normal file
386
docs/engine-reference/unreal/plugins/gameplay-ability-system.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# Unreal Engine 5.7 — Gameplay Ability System (GAS)
|
||||
|
||||
**Last verified:** 2026-02-13
|
||||
**Status:** Production-Ready
|
||||
**Plugin:** `GameplayAbilities` (built-in, enable in Plugins)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**Gameplay Ability System (GAS)** is a modular framework for building abilities, attributes,
|
||||
effects, and gameplay mechanics. It's the standard for RPGs, MOBAs, shooters with abilities,
|
||||
and any game with complex ability systems.
|
||||
|
||||
**Use GAS for:**
|
||||
- Character abilities (spells, skills, attacks)
|
||||
- Attributes (health, mana, stamina, stats)
|
||||
- Buffs/debuffs (temporary effects)
|
||||
- Cooldowns and costs
|
||||
- Damage calculation
|
||||
- Multiplayer-ready ability replication
|
||||
|
||||
---
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### 1. **Ability System Component** (ASC)
|
||||
- The main component that owns abilities, attributes, and effects
|
||||
- Added to Characters or PlayerStates
|
||||
|
||||
### 2. **Gameplay Abilities**
|
||||
- Individual skills/actions (fireball, heal, dash, etc.)
|
||||
- Activated, committed (cost/cooldown), and can be cancelled
|
||||
|
||||
### 3. **Attributes & Attribute Sets**
|
||||
- Stats that can be modified (Health, Mana, Stamina, Strength, etc.)
|
||||
- Stored in Attribute Sets
|
||||
|
||||
### 4. **Gameplay Effects**
|
||||
- Modify attributes (damage, healing, buffs, debuffs)
|
||||
- Can be instant, duration-based, or infinite
|
||||
|
||||
### 5. **Gameplay Tags**
|
||||
- Hierarchical tags for ability logic (e.g., `Ability.Attack.Melee`, `Status.Stunned`)
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Enable Plugin
|
||||
|
||||
`Edit > Plugins > Gameplay Abilities > Enabled > Restart`
|
||||
|
||||
### 2. Add Ability System Component
|
||||
|
||||
```cpp
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "AttributeSet.h"
|
||||
|
||||
UCLASS()
|
||||
class AMyCharacter : public ACharacter {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AMyCharacter() {
|
||||
// Create ASC
|
||||
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));
|
||||
AbilitySystemComponent->SetIsReplicated(true);
|
||||
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
|
||||
|
||||
// Create Attribute Set
|
||||
AttributeSet = CreateDefaultSubobject<UMyAttributeSet>(TEXT("AttributeSet"));
|
||||
}
|
||||
|
||||
protected:
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Abilities")
|
||||
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<const UAttributeSet> AttributeSet;
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Initialize ASC (Important for Multiplayer)
|
||||
|
||||
```cpp
|
||||
void AMyCharacter::PossessedBy(AController* NewController) {
|
||||
Super::PossessedBy(NewController);
|
||||
|
||||
// Server: Initialize ASC
|
||||
if (AbilitySystemComponent) {
|
||||
AbilitySystemComponent->InitAbilityActorInfo(this, this);
|
||||
GiveDefaultAbilities();
|
||||
}
|
||||
}
|
||||
|
||||
void AMyCharacter::OnRep_PlayerState() {
|
||||
Super::OnRep_PlayerState();
|
||||
|
||||
// Client: Initialize ASC
|
||||
if (AbilitySystemComponent) {
|
||||
AbilitySystemComponent->InitAbilityActorInfo(this, this);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Attributes & Attribute Sets
|
||||
|
||||
### Create Attribute Set
|
||||
|
||||
```cpp
|
||||
#include "AttributeSet.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
|
||||
UCLASS()
|
||||
class UMyAttributeSet : public UAttributeSet {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UMyAttributeSet();
|
||||
|
||||
// Health
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_Health)
|
||||
FGameplayAttributeData Health;
|
||||
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Health)
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_MaxHealth)
|
||||
FGameplayAttributeData MaxHealth;
|
||||
ATTRIBUTE_ACCESSORS(UMyAttributeSet, MaxHealth)
|
||||
|
||||
// Mana
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Attributes", ReplicatedUsing = OnRep_Mana)
|
||||
FGameplayAttributeData Mana;
|
||||
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Mana)
|
||||
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
virtual void OnRep_Health(const FGameplayAttributeData& OldHealth);
|
||||
|
||||
UFUNCTION()
|
||||
virtual void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth);
|
||||
|
||||
UFUNCTION()
|
||||
virtual void OnRep_Mana(const FGameplayAttributeData& OldMana);
|
||||
};
|
||||
```
|
||||
|
||||
### Implement Attribute Set
|
||||
|
||||
```cpp
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
UMyAttributeSet::UMyAttributeSet() {
|
||||
// Default values
|
||||
Health = 100.0f;
|
||||
MaxHealth = 100.0f;
|
||||
Mana = 50.0f;
|
||||
}
|
||||
|
||||
void UMyAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, Health, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, Mana, COND_None, REPNOTIFY_Always);
|
||||
}
|
||||
|
||||
void UMyAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) {
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UMyAttributeSet, Health, OldHealth);
|
||||
}
|
||||
|
||||
// Implement other OnRep functions similarly...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Abilities
|
||||
|
||||
### Create Gameplay Ability
|
||||
|
||||
```cpp
|
||||
#include "Abilities/GameplayAbility.h"
|
||||
|
||||
UCLASS()
|
||||
class UGA_Fireball : public UGameplayAbility {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UGA_Fireball() {
|
||||
// Ability config
|
||||
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
|
||||
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::ServerInitiated;
|
||||
|
||||
// Tags
|
||||
AbilityTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Fireball")));
|
||||
}
|
||||
|
||||
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
|
||||
const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override {
|
||||
|
||||
if (!CommitAbility(Handle, ActorInfo, ActivationInfo)) {
|
||||
// Failed to commit (not enough mana, on cooldown, etc.)
|
||||
EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn fireball projectile
|
||||
SpawnFireball();
|
||||
|
||||
// End ability
|
||||
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
|
||||
}
|
||||
|
||||
void SpawnFireball() {
|
||||
// Spawn fireball logic
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Grant Abilities to Character
|
||||
|
||||
```cpp
|
||||
void AMyCharacter::GiveDefaultAbilities() {
|
||||
if (!HasAuthority() || !AbilitySystemComponent) return;
|
||||
|
||||
// Grant abilities
|
||||
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(UGA_Fireball::StaticClass(), 1, INDEX_NONE, this));
|
||||
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(UGA_Heal::StaticClass(), 1, INDEX_NONE, this));
|
||||
}
|
||||
```
|
||||
|
||||
### Activate Ability
|
||||
|
||||
```cpp
|
||||
// Activate by class
|
||||
AbilitySystemComponent->TryActivateAbilityByClass(UGA_Fireball::StaticClass());
|
||||
|
||||
// Activate by tag
|
||||
FGameplayTagContainer TagContainer;
|
||||
TagContainer.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Fireball")));
|
||||
AbilitySystemComponent->TryActivateAbilitiesByTag(TagContainer);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Effects
|
||||
|
||||
### Create Gameplay Effect (Damage)
|
||||
|
||||
```cpp
|
||||
// Create Blueprint: Content Browser > Gameplay > Gameplay Effect
|
||||
|
||||
// OR in C++:
|
||||
UCLASS()
|
||||
class UGE_Damage : public UGameplayEffect {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UGE_Damage() {
|
||||
// Instant damage
|
||||
DurationPolicy = EGameplayEffectDurationType::Instant;
|
||||
|
||||
// Modifier: Reduce Health
|
||||
FGameplayModifierInfo ModifierInfo;
|
||||
ModifierInfo.Attribute = UMyAttributeSet::GetHealthAttribute();
|
||||
ModifierInfo.ModifierOp = EGameplayModOp::Additive;
|
||||
ModifierInfo.ModifierMagnitude = FScalableFloat(-25.0f); // -25 health
|
||||
|
||||
Modifiers.Add(ModifierInfo);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Apply Gameplay Effect
|
||||
|
||||
```cpp
|
||||
// Apply damage to target
|
||||
if (UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target)) {
|
||||
FGameplayEffectContextHandle EffectContext = AbilitySystemComponent->MakeEffectContext();
|
||||
EffectContext.AddSourceObject(this);
|
||||
|
||||
FGameplayEffectSpecHandle SpecHandle = AbilitySystemComponent->MakeOutgoingSpec(
|
||||
UGE_Damage::StaticClass(), 1, EffectContext);
|
||||
|
||||
if (SpecHandle.IsValid()) {
|
||||
AbilitySystemComponent->ApplyGameplayEffectSpecToTarget(*SpecHandle.Data.Get(), TargetASC);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Tags
|
||||
|
||||
### Define Tags
|
||||
|
||||
`Project Settings > Project > Gameplay Tags > Gameplay Tag List`
|
||||
|
||||
Example hierarchy:
|
||||
```
|
||||
Ability
|
||||
├─ Ability.Attack
|
||||
│ ├─ Ability.Attack.Melee
|
||||
│ └─ Ability.Attack.Ranged
|
||||
├─ Ability.Defend
|
||||
└─ Ability.Utility
|
||||
|
||||
Status
|
||||
├─ Status.Stunned
|
||||
├─ Status.Invulnerable
|
||||
└─ Status.Silenced
|
||||
```
|
||||
|
||||
### Use Tags in Abilities
|
||||
|
||||
```cpp
|
||||
UCLASS()
|
||||
class UGA_MeleeAttack : public UGameplayAbility {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UGA_MeleeAttack() {
|
||||
// This ability has these tags
|
||||
AbilityTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack.Melee")));
|
||||
|
||||
// Block these tags while active
|
||||
BlockAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Attack")));
|
||||
|
||||
// Cancel these abilities when activated
|
||||
CancelAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(FName("Ability.Defend")));
|
||||
|
||||
// Can't activate if target has these tags
|
||||
ActivationBlockedTags.AddTag(FGameplayTag::RequestGameplayTag(FName("Status.Stunned")));
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cooldowns & Costs
|
||||
|
||||
### Add Cooldown
|
||||
|
||||
```cpp
|
||||
// In Ability Blueprint or C++:
|
||||
// Create Gameplay Effect with Duration = Cooldown time
|
||||
// Assign to Ability > Cooldown Gameplay Effect Class
|
||||
```
|
||||
|
||||
### Add Cost (Mana)
|
||||
|
||||
```cpp
|
||||
// Create Gameplay Effect that reduces Mana
|
||||
// Assign to Ability > Cost Gameplay Effect Class
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Get Current Attribute Value
|
||||
|
||||
```cpp
|
||||
float CurrentHealth = AbilitySystemComponent->GetNumericAttribute(UMyAttributeSet::GetHealthAttribute());
|
||||
```
|
||||
|
||||
### Listen for Attribute Changes
|
||||
|
||||
```cpp
|
||||
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(UMyAttributeSet::GetHealthAttribute())
|
||||
.AddUObject(this, &AMyCharacter::OnHealthChanged);
|
||||
|
||||
void AMyCharacter::OnHealthChanged(const FOnAttributeChangeData& Data) {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Health: %f"), Data.NewValue);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
- https://docs.unrealengine.com/5.7/en-US/gameplay-ability-system-for-unreal-engine/
|
||||
- https://github.com/tranek/GASDocumentation (community guide)
|
||||
Reference in New Issue
Block a user