claude-code-arcane 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +104 -55
- package/agents/career/career-strategist.md +88 -0
- package/agents/career/cv-reviewer.md +81 -0
- package/agents/career/hiring-manager.md +68 -0
- package/agents/career/mock-interviewer.md +76 -0
- package/agents/freelance/client-screener.md +84 -0
- package/agents/freelance/discovery-call.md +65 -0
- package/agents/freelance/pipeline-strategist.md +99 -0
- package/agents/freelance/proposal-reviewer.md +82 -0
- package/agents/game/ue-blueprint-specialist.md +125 -0
- package/agents/game/ue-gas-specialist.md +133 -0
- package/agents/game/ue-umg-specialist.md +131 -0
- package/dist/cli.js +57 -13
- package/docs/RELEASE-SETUP.md +1 -1
- package/docs/SKILLS-CATALOG.md +67 -4
- package/docs/USER-GUIDE.md +77 -72
- package/docs/agent-hierarchy.md +21 -1
- package/docs/presentations/build_arcane_deck.py +2 -2
- package/docs/presentations/build_arcane_deck_12.py +2 -2
- package/hooks/detect-unreal.sh +90 -0
- package/package.json +2 -2
- package/profiles/freelance.yaml +43 -0
- package/profiles/job-hunt.yaml +5 -2
- package/profiles/unreal-dev.yaml +97 -0
- package/rules/drafter-reviewer.md +16 -3
- package/rules/freelance-guardrails.md +53 -0
- package/rules/gamedev/unreal-code.md +125 -0
- package/skills/career-registry/SKILL.md +95 -0
- package/skills/career-registry/scripts/career_registry.py +488 -0
- package/skills/client-screen/SKILL.md +83 -0
- package/skills/client-screen/references/red-flags.md +95 -0
- package/skills/cover-letter/SKILL.md +4 -3
- package/skills/cv-tailor/SKILL.md +11 -2
- package/skills/freelance-deliver/SKILL.md +90 -0
- package/skills/freelance-hunt/SKILL.md +126 -0
- package/skills/freelance-hunt/references/templates/Connects.md +39 -0
- package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
- package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
- package/skills/freelance-kickoff/SKILL.md +94 -0
- package/skills/freelance-pipeline/SKILL.md +109 -0
- package/skills/freelance-pipeline/scripts/import_history.py +425 -0
- package/skills/freelance-profile/SKILL.md +93 -0
- package/skills/freelance-proposal/SKILL.md +112 -0
- package/skills/freelance-scan/SKILL.md +196 -0
- package/skills/freelance-scan/references/dedup.md +35 -0
- package/skills/freelance-scan/references/platforms.md +167 -0
- package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
- package/skills/install-mcp/SKILL.md +135 -46
- package/skills/install-mcp/references/unreal-operations.md +55 -0
- package/skills/interview-prep/SKILL.md +11 -3
- package/skills/job-aplicar/SKILL.md +5 -1
- package/skills/job-hunt/SKILL.md +17 -0
- package/skills/job-outcome/SKILL.md +15 -1
- package/skills/job-upskill/SKILL.md +10 -2
- package/skills/ue-actor-component-architecture/SKILL.md +509 -0
- package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
- package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
- package/skills/ue-ai-navigation/SKILL.md +526 -0
- package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
- package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
- package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
- package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
- package/skills/ue-animation-system/SKILL.md +521 -0
- package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
- package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
- package/skills/ue-async-threading/SKILL.md +433 -0
- package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
- package/skills/ue-async-threading/references/threading-patterns.md +345 -0
- package/skills/ue-audio-system/SKILL.md +527 -0
- package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
- package/skills/ue-blueprints/SKILL.md +134 -0
- package/skills/ue-blueprints/references/communication.md +82 -0
- package/skills/ue-character-movement/SKILL.md +475 -0
- package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
- package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
- package/skills/ue-cpp-foundations/SKILL.md +533 -0
- package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
- package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
- package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
- package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
- package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
- package/skills/ue-data-assets-tables/SKILL.md +527 -0
- package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
- package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
- package/skills/ue-editor-tools/SKILL.md +523 -0
- package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
- package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
- package/skills/ue-game-features/SKILL.md +477 -0
- package/skills/ue-game-features/references/experience-system.md +222 -0
- package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
- package/skills/ue-gameplay-abilities/SKILL.md +518 -0
- package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
- package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
- package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
- package/skills/ue-gameplay-framework/SKILL.md +466 -0
- package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
- package/skills/ue-input-system/SKILL.md +394 -0
- package/skills/ue-input-system/references/cpp-setup.md +131 -0
- package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
- package/skills/ue-input-system/references/input-action-reference.md +731 -0
- package/skills/ue-mass-entity/SKILL.md +476 -0
- package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
- package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
- package/skills/ue-materials-rendering/SKILL.md +526 -0
- package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
- package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
- package/skills/ue-module-build-system/SKILL.md +487 -0
- package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
- package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
- package/skills/ue-naming-conventions/SKILL.md +142 -0
- package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
- package/skills/ue-naming-conventions/references/content-structure.md +83 -0
- package/skills/ue-networking-replication/SKILL.md +452 -0
- package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
- package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
- package/skills/ue-niagara-effects/SKILL.md +531 -0
- package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
- package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
- package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
- package/skills/ue-packaging/SKILL.md +116 -0
- package/skills/ue-physics-collision/SKILL.md +423 -0
- package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
- package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
- package/skills/ue-procedural-generation/SKILL.md +505 -0
- package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
- package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
- package/skills/ue-project-context/SKILL.md +305 -0
- package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
- package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
- package/skills/ue-serialization-savegames/SKILL.md +524 -0
- package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
- package/skills/ue-state-trees/SKILL.md +489 -0
- package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
- package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
- package/skills/ue-testing-debugging/SKILL.md +520 -0
- package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
- package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
- package/skills/ue-ui-umg-slate/SKILL.md +431 -0
- package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
- package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
- package/skills/ue-world-level-streaming/SKILL.md +518 -0
- package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
- package/templates/gamedev/unreal-project-context.md +107 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# GAS Setup Patterns
|
|
2
|
+
|
|
3
|
+
Initialization sequences and ownership patterns for `UAbilitySystemComponent`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Pattern 1: ASC on PlayerState (Multiplayer Recommended)
|
|
8
|
+
|
|
9
|
+
The ASC lives on `APlayerState`. The PlayerState persists across respawns (Pawn does not), so
|
|
10
|
+
ability grants, active effects, and cooldowns survive death and respawn. The Pawn/Character acts
|
|
11
|
+
as the avatar (the physical representation).
|
|
12
|
+
|
|
13
|
+
### PlayerState
|
|
14
|
+
|
|
15
|
+
```cpp
|
|
16
|
+
// MyPlayerState.h
|
|
17
|
+
#pragma once
|
|
18
|
+
#include "GameFramework/PlayerState.h"
|
|
19
|
+
#include "AbilitySystemInterface.h"
|
|
20
|
+
#include "MyPlayerState.generated.h"
|
|
21
|
+
|
|
22
|
+
class UAbilitySystemComponent;
|
|
23
|
+
class UMyHealthSet;
|
|
24
|
+
|
|
25
|
+
UCLASS()
|
|
26
|
+
class AMyPlayerState : public APlayerState, public IAbilitySystemInterface
|
|
27
|
+
{
|
|
28
|
+
GENERATED_BODY()
|
|
29
|
+
public:
|
|
30
|
+
AMyPlayerState();
|
|
31
|
+
|
|
32
|
+
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
|
|
33
|
+
|
|
34
|
+
UMyHealthSet* GetHealthSet() const { return HealthSet; }
|
|
35
|
+
|
|
36
|
+
protected:
|
|
37
|
+
// ASC lives here; created as default subobject
|
|
38
|
+
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GAS")
|
|
39
|
+
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
|
|
40
|
+
|
|
41
|
+
// AttributeSet created as subobject of ASC's outer (PlayerState)
|
|
42
|
+
UPROPERTY()
|
|
43
|
+
TObjectPtr<UMyHealthSet> HealthSet;
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```cpp
|
|
48
|
+
// MyPlayerState.cpp
|
|
49
|
+
#include "MyPlayerState.h"
|
|
50
|
+
#include "AbilitySystemComponent.h"
|
|
51
|
+
#include "Attributes/MyHealthSet.h"
|
|
52
|
+
|
|
53
|
+
AMyPlayerState::AMyPlayerState()
|
|
54
|
+
{
|
|
55
|
+
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("ASC"));
|
|
56
|
+
|
|
57
|
+
// Mixed: owner/autonomous proxy gets full GE info; simulated proxies get minimal
|
|
58
|
+
AbilitySystemComponent->SetIsReplicated(true);
|
|
59
|
+
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
|
|
60
|
+
|
|
61
|
+
// AttributeSet is a subobject of the PlayerState; ASC auto-discovers it
|
|
62
|
+
HealthSet = CreateDefaultSubobject<UMyHealthSet>(TEXT("HealthSet"));
|
|
63
|
+
|
|
64
|
+
// PlayerState replication required
|
|
65
|
+
NetUpdateFrequency = 100.f;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
UAbilitySystemComponent* AMyPlayerState::GetAbilitySystemComponent() const
|
|
69
|
+
{
|
|
70
|
+
return AbilitySystemComponent;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Character (Avatar)
|
|
75
|
+
|
|
76
|
+
```cpp
|
|
77
|
+
// MyCharacter.h
|
|
78
|
+
#pragma once
|
|
79
|
+
#include "GameFramework/Character.h"
|
|
80
|
+
#include "AbilitySystemInterface.h"
|
|
81
|
+
#include "MyCharacter.generated.h"
|
|
82
|
+
|
|
83
|
+
UCLASS()
|
|
84
|
+
class AMyCharacter : public ACharacter, public IAbilitySystemInterface
|
|
85
|
+
{
|
|
86
|
+
GENERATED_BODY()
|
|
87
|
+
public:
|
|
88
|
+
// Delegates to PlayerState's ASC
|
|
89
|
+
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
|
|
90
|
+
|
|
91
|
+
// Server: Called when controller possesses this pawn
|
|
92
|
+
virtual void PossessedBy(AController* NewController) override;
|
|
93
|
+
|
|
94
|
+
// Client: Called when PlayerState replicates
|
|
95
|
+
virtual void OnRep_PlayerState() override;
|
|
96
|
+
|
|
97
|
+
private:
|
|
98
|
+
void InitGAS();
|
|
99
|
+
void GiveDefaultAbilities(); // Server only
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```cpp
|
|
104
|
+
// MyCharacter.cpp
|
|
105
|
+
#include "MyCharacter.h"
|
|
106
|
+
#include "MyPlayerState.h"
|
|
107
|
+
#include "AbilitySystemComponent.h"
|
|
108
|
+
|
|
109
|
+
UAbilitySystemComponent* AMyCharacter::GetAbilitySystemComponent() const
|
|
110
|
+
{
|
|
111
|
+
const AMyPlayerState* PS = GetPlayerState<AMyPlayerState>();
|
|
112
|
+
return PS ? PS->GetAbilitySystemComponent() : nullptr;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void AMyCharacter::PossessedBy(AController* NewController)
|
|
116
|
+
{
|
|
117
|
+
Super::PossessedBy(NewController);
|
|
118
|
+
InitGAS();
|
|
119
|
+
GiveDefaultAbilities(); // Authority only, safe here
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
void AMyCharacter::OnRep_PlayerState()
|
|
123
|
+
{
|
|
124
|
+
Super::OnRep_PlayerState();
|
|
125
|
+
InitGAS(); // Client side initialization
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
void AMyCharacter::InitGAS()
|
|
129
|
+
{
|
|
130
|
+
AMyPlayerState* PS = GetPlayerState<AMyPlayerState>();
|
|
131
|
+
if (!PS) return;
|
|
132
|
+
|
|
133
|
+
UAbilitySystemComponent* ASC = PS->GetAbilitySystemComponent();
|
|
134
|
+
if (!ASC) return;
|
|
135
|
+
|
|
136
|
+
// OwnerActor = who logically owns the ASC (PlayerState)
|
|
137
|
+
// AvatarActor = the physical actor in the world (Character)
|
|
138
|
+
ASC->InitAbilityActorInfo(PS, this);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void AMyCharacter::GiveDefaultAbilities()
|
|
142
|
+
{
|
|
143
|
+
if (!HasAuthority()) return;
|
|
144
|
+
|
|
145
|
+
UAbilitySystemComponent* ASC = GetAbilitySystemComponent();
|
|
146
|
+
if (!ASC) return;
|
|
147
|
+
|
|
148
|
+
// Grant abilities from a data-driven list
|
|
149
|
+
for (const TSubclassOf<UGameplayAbility>& AbilityClass : DefaultAbilities)
|
|
150
|
+
{
|
|
151
|
+
FGameplayAbilitySpec Spec(AbilityClass, 1 /*Level*/);
|
|
152
|
+
ASC->GiveAbility(Spec);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Respawn Handling
|
|
158
|
+
|
|
159
|
+
When the Pawn is destroyed and respawned, the new Pawn must re-init its actor info:
|
|
160
|
+
|
|
161
|
+
```cpp
|
|
162
|
+
void AMyGameMode::RespawnPlayer(AController* Controller)
|
|
163
|
+
{
|
|
164
|
+
// Destroy old pawn, spawn new one at respawn location
|
|
165
|
+
APawn* OldPawn = Controller->GetPawn();
|
|
166
|
+
if (OldPawn) OldPawn->Destroy();
|
|
167
|
+
|
|
168
|
+
AMyCharacter* NewPawn = GetWorld()->SpawnActor<AMyCharacter>(
|
|
169
|
+
CharacterClass, RespawnTransform);
|
|
170
|
+
Controller->Possess(NewPawn);
|
|
171
|
+
// PossessedBy fires → InitGAS → InitAbilityActorInfo with old PlayerState ASC
|
|
172
|
+
// Active effects and cooldowns on the ASC survive the respawn
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Pattern 2: ASC on Character (Single-Player / AI)
|
|
179
|
+
|
|
180
|
+
Simpler setup. The ASC and AttributeSet both live on the Pawn. Use for AI actors or
|
|
181
|
+
single-player games where persistence across respawns is not needed.
|
|
182
|
+
|
|
183
|
+
```cpp
|
|
184
|
+
// MyAICharacter.h
|
|
185
|
+
#pragma once
|
|
186
|
+
#include "GameFramework/Character.h"
|
|
187
|
+
#include "AbilitySystemInterface.h"
|
|
188
|
+
#include "MyAICharacter.generated.h"
|
|
189
|
+
|
|
190
|
+
UCLASS()
|
|
191
|
+
class AMyAICharacter : public ACharacter, public IAbilitySystemInterface
|
|
192
|
+
{
|
|
193
|
+
GENERATED_BODY()
|
|
194
|
+
public:
|
|
195
|
+
AMyAICharacter();
|
|
196
|
+
|
|
197
|
+
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
|
|
198
|
+
virtual void BeginPlay() override;
|
|
199
|
+
|
|
200
|
+
protected:
|
|
201
|
+
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GAS")
|
|
202
|
+
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
|
|
203
|
+
|
|
204
|
+
UPROPERTY()
|
|
205
|
+
TObjectPtr<UMyHealthSet> HealthSet;
|
|
206
|
+
};
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
```cpp
|
|
210
|
+
// MyAICharacter.cpp
|
|
211
|
+
#include "MyAICharacter.h"
|
|
212
|
+
#include "AbilitySystemComponent.h"
|
|
213
|
+
#include "Attributes/MyHealthSet.h"
|
|
214
|
+
|
|
215
|
+
AMyAICharacter::AMyAICharacter()
|
|
216
|
+
{
|
|
217
|
+
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("ASC"));
|
|
218
|
+
AbilitySystemComponent->SetIsReplicated(true);
|
|
219
|
+
// Minimal: AI does not need full GE replication on simulated proxies
|
|
220
|
+
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);
|
|
221
|
+
|
|
222
|
+
HealthSet = CreateDefaultSubobject<UMyHealthSet>(TEXT("HealthSet"));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
UAbilitySystemComponent* AMyAICharacter::GetAbilitySystemComponent() const
|
|
226
|
+
{
|
|
227
|
+
return AbilitySystemComponent;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
void AMyAICharacter::BeginPlay()
|
|
231
|
+
{
|
|
232
|
+
Super::BeginPlay();
|
|
233
|
+
// For ASC on Pawn, OwnerActor == AvatarActor == this
|
|
234
|
+
AbilitySystemComponent->InitAbilityActorInfo(this, this);
|
|
235
|
+
|
|
236
|
+
if (HasAuthority())
|
|
237
|
+
{
|
|
238
|
+
// Grant AI abilities
|
|
239
|
+
for (const TSubclassOf<UGameplayAbility>& AbilityClass : DefaultAbilities)
|
|
240
|
+
{
|
|
241
|
+
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(AbilityClass, 1));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Attribute Initialization from CurveTable
|
|
250
|
+
|
|
251
|
+
GAS supports initializing attributes from a `UCurveTable` for data-driven level scaling.
|
|
252
|
+
Row format: `[GroupName].[AttributeSetName].[AttributeName]`
|
|
253
|
+
|
|
254
|
+
Example rows:
|
|
255
|
+
```
|
|
256
|
+
Default.MyHealthSet.Health | 100 | 150 | 200 | ... (per level)
|
|
257
|
+
Default.MyHealthSet.MaxHealth | 100 | 150 | 200 | ...
|
|
258
|
+
Hero1.MyHealthSet.Health | 80 | 120 | 160 | ...
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```cpp
|
|
262
|
+
// Call after InitAbilityActorInfo, on server only:
|
|
263
|
+
UAbilitySystemGlobals::Get().GetAttributeSetInitter()->InitAttributeSetDefaults(
|
|
264
|
+
AbilitySystemComponent,
|
|
265
|
+
FName("Default"), // GroupName matches CurveTable row prefix
|
|
266
|
+
PlayerLevel,
|
|
267
|
+
true /*bInitialInit*/);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Ability Spec Handle Tracking
|
|
273
|
+
|
|
274
|
+
Store handles to remove or modify abilities later:
|
|
275
|
+
|
|
276
|
+
```cpp
|
|
277
|
+
// In a component or character header:
|
|
278
|
+
UPROPERTY()
|
|
279
|
+
TArray<FGameplayAbilitySpecHandle> GrantedAbilityHandles;
|
|
280
|
+
|
|
281
|
+
// Granting:
|
|
282
|
+
FGameplayAbilitySpecHandle Handle = AbilitySystemComponent->GiveAbility(
|
|
283
|
+
FGameplayAbilitySpec(UMyAbility::StaticClass(), 1));
|
|
284
|
+
GrantedAbilityHandles.Add(Handle);
|
|
285
|
+
|
|
286
|
+
// Removing a specific ability:
|
|
287
|
+
AbilitySystemComponent->ClearAbility(GrantedAbilityHandles[0]);
|
|
288
|
+
|
|
289
|
+
// Removing all granted abilities:
|
|
290
|
+
for (const FGameplayAbilitySpecHandle& H : GrantedAbilityHandles)
|
|
291
|
+
{
|
|
292
|
+
AbilitySystemComponent->ClearAbility(H);
|
|
293
|
+
}
|
|
294
|
+
GrantedAbilityHandles.Empty();
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Tag Event Registration
|
|
300
|
+
|
|
301
|
+
Listen for gameplay tag additions/removals on the ASC:
|
|
302
|
+
|
|
303
|
+
```cpp
|
|
304
|
+
void AMyCharacter::InitGAS()
|
|
305
|
+
{
|
|
306
|
+
// ... init actor info ...
|
|
307
|
+
|
|
308
|
+
// Register delegate for stunned state:
|
|
309
|
+
AbilitySystemComponent->RegisterGameplayTagEvent(
|
|
310
|
+
FGameplayTag::RequestGameplayTag("State.Stunned"),
|
|
311
|
+
EGameplayTagEventType::NewOrRemoved)
|
|
312
|
+
.AddUObject(this, &AMyCharacter::OnStunnedTagChanged);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
void AMyCharacter::OnStunnedTagChanged(const FGameplayTag Tag, int32 NewCount)
|
|
316
|
+
{
|
|
317
|
+
if (NewCount > 0)
|
|
318
|
+
{
|
|
319
|
+
// Stunned: disable movement, play stun animation
|
|
320
|
+
}
|
|
321
|
+
else
|
|
322
|
+
{
|
|
323
|
+
// No longer stunned: re-enable movement
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Attribute Value Delegates
|
|
331
|
+
|
|
332
|
+
React to attribute changes (e.g., update UI health bar):
|
|
333
|
+
|
|
334
|
+
```cpp
|
|
335
|
+
void UMyHealthWidget::BindToASC(UAbilitySystemComponent* ASC)
|
|
336
|
+
{
|
|
337
|
+
if (!ASC) return;
|
|
338
|
+
|
|
339
|
+
HealthChangedDelegateHandle = ASC->GetGameplayAttributeValueChangeDelegate(
|
|
340
|
+
UMyHealthSet::GetHealthAttribute())
|
|
341
|
+
.AddUObject(this, &UMyHealthWidget::OnHealthChanged);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
void UMyHealthWidget::OnHealthChanged(const FOnAttributeChangeData& Data)
|
|
345
|
+
{
|
|
346
|
+
UpdateHealthBar(Data.NewValue);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
void UMyHealthWidget::UnbindFromASC(UAbilitySystemComponent* ASC)
|
|
350
|
+
{
|
|
351
|
+
if (!ASC) return;
|
|
352
|
+
ASC->GetGameplayAttributeValueChangeDelegate(UMyHealthSet::GetHealthAttribute())
|
|
353
|
+
.Remove(HealthChangedDelegateHandle);
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Replication Mode Summary
|
|
360
|
+
|
|
361
|
+
| Mode | GE Replication | Tag Replication | Use Case |
|
|
362
|
+
|------|----------------|-----------------|----------|
|
|
363
|
+
| `Minimal` | None to simulated | Minimal tags only | AI, non-player actors |
|
|
364
|
+
| `Mixed` | Full to owner/autonomous, minimal to simulated | Full | Player-controlled characters |
|
|
365
|
+
| `Full` | Full to everyone | Full | Single-player or small games |
|
|
366
|
+
|
|
367
|
+
**Critical:** `Mixed` mode requires the ASC owner to be the PlayerState (or any actor
|
|
368
|
+
not the Pawn). If the ASC is on the Pawn with `Mixed` mode, tag replication to simulated
|
|
369
|
+
proxies will not work correctly. Use `Full` if ASC must be on the Pawn in multiplayer.
|