Let's talk

RSAbilitySystemLibrary.h

Source/RSGasHelpers/Public/RSAbilitySystemLibrary.h Raw Download ZIP

Click a line number to link it. Shift-click to select a range.

1// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Kismet/BlueprintFunctionLibrary.h"
7#include "GameplayTagContainer.h"
8#include "GameplayEffectTypes.h"
9#include "RSAbilitySystemLibrary.generated.h"
10
11class UAbilitySystemComponent;
12class UGameplayEffect;
13
14/** Why an activate-by-tag call did or did not start an ability. */
15UENUM(BlueprintType)
16enum class ERSActivateResult : uint8
17{
18 /** No ability system component was found on the actor. */
19 NoASC,
20 /** The ASC has no granted ability whose tags match. */
21 NotGranted,
22 /** A matching ability exists but could not activate (tags, cost, cooldown, net policy). */
23 Blocked,
24 /** At least one matching ability was activated or sent to the server for activation. */
25 Activated
26};
27
28/**
29 * Blueprint and C++ helpers for the Gameplay Ability System in multiplayer games.
30 * Each function has a matching tutorial at https://reignancestudios.com/tutorials
31 */
32UCLASS()
33class RSGASHELPERS_API URSAbilitySystemLibrary : public UBlueprintFunctionLibrary
34{
35 GENERATED_BODY()
36
37public:
38 /**
39 * Finds the ability system component for an actor, including the common
40 * "ASC lives on the PlayerState" setup. Checks, in order: the actor itself,
41 * its PlayerState (pawns), its controller's PlayerState, its owner.
42 */
43 UFUNCTION(BlueprintPure, Category = "RS|GAS", meta = (DefaultToSelf = "Actor"))
44 static UAbilitySystemComponent* FindAbilitySystemComponent(const AActor* Actor);
45
46 /**
47 * Activates abilities matching a tag and says why it failed when it does.
48 * Call it on the owning client for predicted abilities; the ASC handles the server round trip.
49 */
50 UFUNCTION(BlueprintCallable, Category = "RS|GAS", meta = (DefaultToSelf = "Actor"))
51 static ERSActivateResult TryActivateAbilityByTag(AActor* Actor, FGameplayTag AbilityTag, bool bAllowRemoteActivation = true);
52
53 /**
54 * Adds a loose gameplay tag on the server and replicates it to every client.
55 * Plain AddLooseGameplayTag never replicates. Does nothing without authority.
56 * Returns true when the tag was added.
57 */
58 UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "RS|GAS", meta = (DefaultToSelf = "Actor"))
59 static bool AddReplicatedLooseTag(AActor* Actor, FGameplayTag Tag);
60
61 /** Removes a tag added with AddReplicatedLooseTag, on the server and on every client. */
62 UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "RS|GAS", meta = (DefaultToSelf = "Actor"))
63 static bool RemoveReplicatedLooseTag(AActor* Actor, FGameplayTag Tag);
64
65 /**
66 * Builds an outgoing effect spec and fills SetByCaller magnitudes in one call.
67 * Missing SetByCaller values are the most common cause of "effect applied with 0".
68 */
69 UFUNCTION(BlueprintCallable, Category = "RS|GAS")
70 static FGameplayEffectSpecHandle MakeSpecWithSetByCaller(
71 UAbilitySystemComponent* ASC,
72 TSubclassOf<UGameplayEffect> EffectClass,
73 float Level,
74 const TMap<FGameplayTag, float>& SetByCallerMagnitudes);
75
76 /**
77 * Seconds left on the cooldown that grants CooldownTag (e.g. Cooldown.Dash), and its full duration.
78 * Returns false when no active effect grants the tag. On the owning client it includes the
79 * predicted cooldown, so a cooldown widget starts the moment the ability is pressed.
80 */
81 UFUNCTION(BlueprintPure, Category = "RS|GAS", meta = (DefaultToSelf = "Actor"))
82 static bool GetCooldownRemainingByTag(const AActor* Actor, FGameplayTag CooldownTag, float& TimeRemaining, float& Duration);
83
84 /**
85 * Input pressed for every granted ability whose tags match AbilityTag. Starts the ability if it is
86 * not active; if it is, forwards the press to it (WaitInputPress) with its prediction key.
87 * Call it on the owning client from an input event. Returns how many abilities matched.
88 */
89 UFUNCTION(BlueprintCallable, Category = "RS|GAS|Input", meta = (DefaultToSelf = "Actor"))
90 static int32 PressAbilityInputByTag(AActor* Actor, FGameplayTag AbilityTag);
91
92 /** Input released for every granted ability matching AbilityTag (WaitInputRelease, charge-and-release abilities). */
93 UFUNCTION(BlueprintCallable, Category = "RS|GAS|Input", meta = (DefaultToSelf = "Actor"))
94 static int32 ReleaseAbilityInputByTag(AActor* Actor, FGameplayTag AbilityTag);
95
96 /**
97 * Returns a readable snapshot of an ASC: net role, owner and avatar, owned tags,
98 * granted and active abilities, active effects and every attribute value.
99 * Print it on the server and on a client side by side to find a desync.
100 */
101 UFUNCTION(BlueprintCallable, Category = "RS|GAS|Debug", meta = (DefaultToSelf = "Actor"))
102 static FString DumpAbilitySystemState(const AActor* Actor);
103};

Still desyncing in packaged builds?

Free code fixes one symptom. A Diagnostic finds the cause across your project in two days.