GiveAbilityAndActivateOnce is a small function on the Ability System Component for abilities that should run once and then be removed.
Most abilities in the Gameplay Ability System ( GAS ) are granted once, when the character spawns, and after that you activate them many times through input or gameplay events. Your dodge, your attacks, your block, all of them work like this.
Other abilities only need to run one time. Ex: a scripted knockdown, the victim side of an execution, or a command from the server to do something now.
On Lords of the Fallen I worked on the execution system, and the victim side of an execution is this kind of ability: the target receives the “get executed” order, plays it, and should not keep that ability afterwards.
The manual way
You can handle these abilities by hand:
- GiveAbility to grant it
- TryActivateAbility to run it
- ClearAbility to remove it once it ends
If you forget to clear the spec when the ability ends, it stays on the ASC even though it will not activate again. After a while these specs accumulate, and everything that goes through GetActivatableAbilities() has to skip them.
Fortunately the ASC already has a function for this:
// GameplayAbilities/Public/AbilitySystemComponent.h
FGameplayAbilitySpecHandle GiveAbilityAndActivateOnce(
FGameplayAbilitySpec& AbilitySpec,
const FGameplayEventData* GameplayEventData = nullptr);
What the function does
It does the three steps for you: it grants the spec, it tries to activate it, and it removes the grant afterwards.
If the activation fails, the spec is cleared on the spot and you get back an invalid handle, so you can check the handle to know if it ran or not. If the activation succeeds, the spec is marked to be removed when the ability ends. This also works with latent abilities, so the ability can play a montage, wait on ability tasks, take a couple of seconds… and the grant will still be cleaned up when EndAbility runs.
Some things to take into account:
- It only works with authority. Granting abilities is a server operation, so on a client the function simply does nothing.
- The ability needs to be instanced, and not Local Only. This is fine, an ability that plays montages and waits on tasks would be instanced anyway.
- Do not store the handle. The spec removes itself, so the handle is only good to check the immediate result. If some other code looks it up later, the spec will already be gone.
Example: a knockdown bolt
Here is how I use it in a projectile that knocks down whatever it hits:
void AKnockdownBolt::OnProjectileHit(AActor* HitActor, const FHitResult& Hit)
{
if (!HasAuthority())
{
return;
}
UAbilitySystemComponent* TargetASC =
UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(HitActor);
if (!TargetASC)
{
return;
}
// The event data is your payload: who shot, where it hit, how hard.
FGameplayEventData EventData;
EventData.Instigator = GetInstigator();
EventData.Target = HitActor;
EventData.EventMagnitude = KnockdownForce;
EventData.ContextHandle = TargetASC->MakeEffectContext();
EventData.ContextHandle.AddHitResult(Hit);
FGameplayAbilitySpec Spec(UGA_GetKnockedDown::StaticClass(), /*Level=*/1, INDEX_NONE, this);
TargetASC->GiveAbilityAndActivateOnce(Spec, &EventData);
}
The second parameter, FGameplayEventData, arrives to the ability as TriggerEventData. The knockdown ability can read where it was hit and react to it:
void UGA_GetKnockedDown::ActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData)
{
const FHitResult* Hit = TriggerEventData
? TriggerEventData->ContextHandle.GetHitResult()
: nullptr;
// Commit, pick the directional knockdown montage from the hit direction,
// play it with Play Montage and Wait, push the character back,
// and call EndAbility when the montage finishes.
}
I like having the reaction in the ability, as it runs on the target and can use the target’s tags and attributes. If a boss has a StatusImmuneKnockdown tag in the Activation Blocked Tags of the ability, the activation fails and cleans up the spec too. We do not need to check that tag in the projectile.
One networking thing: the activation happens on the server. For AI targets, Server Only is enough, as the montage plays through the ASC and replicates by default. For player targets you want Server Initiated, so that the owning client also runs the ability.
Other places where this is useful
In an execution, the attacker runs their normal finisher ability and the victim receives the “get executed” ability with GiveAbilityAndActivateOnce.
A trap can give you a GA_Trapped ability on overlap, so every character does not have to carry it in advance. A boss phase transition can work the same way: roar, jump to the center of the arena, then remove the ability once it ends.
You can also call it from level scripting to make a character perform an ability without changing how that character was set up.
When not to use it
If the behavior should exist for some time instead of being a single moment, this is not the tool. Ex: “While burning, you have a Panic ability”. That is a temporary ability, not a command, so you grant it through a Gameplay Effect with the Grant Abilities component and let the lifetime of the effect add and remove the ability. I talked about those components in the Gameplay Effect Components post.
That leaves us with these options:
- Permanent ability: GiveAbility.
- Temporary ability tied to an effect: grant it through the Gameplay Effect.
- Single command: GiveAbilityAndActivateOnce.
By the way, if you want to find candidates in your own project, search for TryActivateAbility. If some of them come right after a GiveAbility, followed by a manual ClearAbility or not followed by anything at all, you have found one.
Recap
GiveAbilityAndActivateOnce grants the spec and removes it when the ability ends, including latent abilities. A failed activation removes it immediately and returns an invalid handle. The call is server only, the ability must be instanced and not Local Only, and the handle should not be kept around.
I use GiveAbility for permanent abilities, a Gameplay Effect for temporary ones, and GiveAbilityAndActivateOnce for single commands.


