Cue Manager¶
The UGameplayCueManager is a singleton (technically a UDataAsset) that acts as the central routing hub for all Gameplay Cue events. It discovers cue notify classes, loads them, matches incoming cue tags to the right notify, manages the actor recycle pool, and handles batching.
You'll rarely call into the manager directly during normal development -- the ASC handles routing for you. But understanding the manager is essential for configuration, optimization, and debugging cue issues.
How Routing Works¶
When a cue event arrives (from an effect, manual trigger, or animation), the flow through the manager is:
HandleGameplayCue(TargetActor, Tag, EventType, Parameters)
│
├─ 1. ShouldSuppressGameplayCues(TargetActor)
│ → If true, cue is silently dropped
│
├─ 2. TranslateGameplayCue(Tag, TargetActor, Parameters)
│ → Tag may be remapped via GameplayCueTranslator
│
├─ 3. RouteGameplayCue(TargetActor, Tag, EventType, Parameters)
│ ├─ Check IGameplayCueInterface on target actor
│ └─ Look up tag in GameplayCueSet
│ ├─ Found → invoke notify class
│ └─ Not found → HandleMissingGameplayCue()
│ ├─ Sync load? → load and invoke
│ ├─ Async load? → queue for later
│ └─ Neither → silently ignored
│
└─ OnRouteGameplayCue delegate fires (for custom observers)
Execution Options¶
The EGameplayCueExecutionOptions flags let callers skip parts of the pipeline:
| Flag | Effect |
|---|---|
IgnoreInterfaces |
Skip IGameplayCueInterface check |
IgnoreNotifies |
Skip notify class lookup/spawn |
IgnoreTranslation |
Skip tag translation step |
IgnoreSuppression |
Force execution even if suppressed |
IgnoreDebug |
Don't show debug visualizations |
GameplayCueSet¶
The UGameplayCueSet is the lookup table that maps FGameplayTag to cue notify class/object data. The manager maintains two sets:
| Set | Purpose | When Used |
|---|---|---|
| RuntimeGameplayCueObjectLibrary.CueSet | The "always loaded" set | At runtime |
| EditorGameplayCueObjectLibrary.CueSet | All discoverable cues | Editor only (GameplayCue editor) |
At startup, the manager scans the configured paths (see below), finds all cue notify assets, and registers them in the runtime CueSet.
Scan Paths and Configuration¶
Where the Manager Looks¶
The manager discovers cue notifies by scanning content directories. The paths are configured in Project Settings > Gameplay Abilities Settings:
Or in C++ via UAbilitySystemGlobals:
// In your AbilitySystemGlobals subclass
TArray<FString> UMyAbilitySystemGlobals::GetGameplayCueNotifyPaths()
{
TArray<FString> Paths = Super::GetGameplayCueNotifyPaths();
Paths.Add(TEXT("/Game/MyPlugin/Cues"));
return Paths;
}
You can also add/remove paths at runtime:
UGameplayCueManager* CueManager = UAbilitySystemGlobals::Get().GetGameplayCueManager();
CueManager->AddGameplayCueNotifyPath(TEXT("/Game/DLC/Cues"), true);
CueManager->RemoveGameplayCueNotifyPath(TEXT("/Game/OldCues"), true);
The second parameter (bShouldRescanCueAssets) triggers a re-scan of the object libraries.
Auto-Tagging from Asset Name¶
Cue notifies can have their tag set automatically based on their asset name. If you name your asset GC_Hit_Physical_Slash, the system can derive GameplayCue.Hit.Physical.Slash. This is handled by UAbilitySystemGlobals::DeriveGameplayCueTagFromAssetName.
Naming convention
Name your cue assets to match their tag hierarchy. Prefix with GC_ by convention, then replace dots with underscores: GC_Status_Burning maps to GameplayCue.Status.Burning.
Loading Behavior¶
Startup Loading¶
By default, the manager async-loads all cue notifies found in the configured paths at startup. The behavior is controlled by virtual functions you can override:
| Method | Default | Effect |
|---|---|---|
ShouldSyncScanRuntimeObjectLibraries() |
Varies | Force sync scan of asset registry |
ShouldSyncLoadRuntimeObjectLibraries() |
false |
Sync load all cues at startup |
ShouldAsyncLoadRuntimeObjectLibraries() |
true |
Async load cues at startup |
ShouldAsyncLoadObjectLibrariesAtStart() |
true |
Start async load on manager creation |
ShouldLoadGameplayCueAssetData() |
true |
Per-asset filter for loading |
Missing Cue Handling¶
When a cue event fires for a tag that hasn't been loaded yet:
| Method | Default | Behavior |
|---|---|---|
ShouldSyncLoadMissingGameplayCues() |
false |
Block and load immediately |
ShouldAsyncLoadMissingGameplayCues() |
false |
Start async load, queue the event |
If both return false, the cue is silently dropped. Override HandleMissingGameplayCue() for custom handling.
Sync loading in shipping builds
Sync loading cues at runtime causes hitches. It's useful during development to catch missing cues, but disable it for shipping. See Lazy Loading for the recommended approach.
Async Load Pending Cues¶
When a cue is async-loaded due to a missing class, the manager caches pending events in AsyncLoadPendingGameplayCues. Once the class finishes loading, the cached events are replayed. This is transparent to the gameplay code but means there's a brief delay before the cue plays.
Actor Recycling¶
For instanced cue notifies (AGameplayCueNotify_Actor and subclasses), the manager maintains a recycle pool to avoid the cost of spawning and destroying actors repeatedly.
The flow:
- Cue fires for the first time → actor is spawned normally
- Cue ends →
Recycle()is called on the actor → actor hides and goes into the pool - Same cue type needed again →
FindRecycledCue()finds a pooled actor →ReuseAfterRecycle()is called
Check if recycling is enabled with UGameplayCueManager::IsGameplayCueRecylingEnabled().
Preallocation¶
For cue actors that set NumPreallocatedInstances > 0, the manager pre-spawns that many actors at startup via UpdatePreallocation(). Call this from your GameState or game mode during initialization:
UGameplayCueManager* CueManager = UAbilitySystemGlobals::Get().GetGameplayCueManager();
CueManager->ResetPreallocation(GetWorld());
CueManager->UpdatePreallocation(GetWorld());
GameplayCueTranslator¶
The FGameplayCueTranslationManager (accessible via TranslationManager on the cue manager) allows tag remapping before lookup. This is useful for:
- Mapping generic tags to game-specific ones based on context (e.g.,
GameplayCue.Hit.Physical→GameplayCue.Hit.Physical.Swordbased on the equipped weapon) - Overriding cues per character class or skin
- A/B testing different cue variants
Translation happens in step 2 of the routing pipeline, before the notify lookup. Implement custom translators by working with the FGameplayCueTranslationManager API.
Batching and Pending Cues¶
The manager supports batching cue events to reduce RPC overhead. This is managed through a send context:
// Start batching
CueManager->StartGameplayCueSendContext();
// ... multiple cue events are queued as FGameplayCuePendingExecute ...
// Stop batching and flush
CueManager->EndGameplayCueSendContext();
The engine uses FScopedGameplayCueSendContext as an RAII wrapper. While a send context is active, cues are accumulated in PendingExecuteCues instead of being sent immediately. When the last context closes, FlushPendingCues() is called and the batch goes out.
The OnFlushPendingCues delegate fires during flush, which is useful for custom batching strategies.
For more on batching optimization, see Cue Batching and Batching (Networking).
Overriding the Manager¶
To customize the manager, create a subclass and register it:
Step 1: Subclass¶
UCLASS()
class UMyGameplayCueManager : public UGameplayCueManager
{
GENERATED_BODY()
virtual bool ShouldSuppressGameplayCues(AActor* TargetActor) override
{
// Example: suppress cues during loading screens
if (IsInLoadingScreen())
return true;
return Super::ShouldSuppressGameplayCues(TargetActor);
}
};
Step 2: Register in Project Settings¶
In Project Settings > Gameplay Abilities Settings, set the Global GameplayCue Manager Class to your subclass.
Or via your DefaultGame.ini:
[/Script/GameplayAbilities.GameplayAbilitiesDeveloperSettings]
GlobalGameplayCueManagerClass=/Script/MyGame.MyGameplayCueManager
Common Override Points¶
| Virtual | Purpose |
|---|---|
ShouldSuppressGameplayCues |
Reject cues globally (loading, dead actors) |
HandleMissingGameplayCue |
Custom behavior when a cue class isn't loaded |
ShouldLoadGameplayCueAssetData |
Filter which assets to include |
ProcessPendingCueExecute |
Custom batch processing |
DoesPendingCueExecuteMatch |
Custom deduplication of pending cues |
GetInstancedCueActor |
Custom instance management |
GetAlwaysLoadedGameplayCuePaths |
Dynamic path configuration |
Debugging¶
The manager has a PrintGameplayCueNotifyMap() function that dumps the entire tag-to-class mapping to the log. Useful for verifying that your cues are discovered:
See Debugging for more diagnostic tools.
Related Pages¶
- Cue Notify Types -- the six notify classes
- Cue Parameters -- data passed to cues
- Cue Batching -- reducing RPC overhead
- Lazy Loading -- async loading strategies
- AbilitySystemGlobals -- global configuration