Cascade Combat System
A modular action-combat framework for Unreal Engine 5. Node-based combo trees, animation-driven abilities, melee detection, projectiles, targeting, and hit reactions, all built on GAS, multiplayer-ready without writing replication code.
Overview
Cascade Combat System is an action-combat framework for Unreal Engine 5 built on the Gameplay Ability System. It solves the problem of wiring together melee detection, combo sequencing, input buffering, targeting, weakspots, and hit reactions without rewriting GAS boilerplate for every project. You define UCascadeComboDefinition data assets in a node graph editor, attach UCascadeAbilitySystemComponent to your characters, and call InitializeCombat, the plugin handles input routing, window management, and networking from there.
Damage authoring lives on one structure: FCascadeDamageDescriptor. Each ability holds a BaseDamage descriptor (and an optional per-window override map) with the GE class, magnitude, hit tags, hit caps, weakspot resolution mode, and a project-extensible ProjectPayload (FInstancedStruct) where your game's faction / damage type / knockback / hit-stop fields live. The plugin reads only the universal fields; project listeners on OnPreHitResolve and OnHitDetected consume the rest.
Movement is fully decoupled. Plugin features (anim flying-mode, drag-target freeze, gravity GE, airborne tag, cancel-on-input, directional combos) call through ICascadeMovementBridge. A CMC-backed default ships with the plugin; projects on Mover, GMC, or custom systems supply their own bridge component. No coupling to a specific movement framework.
Node-Based Combos
Build combo trees visually in the editor. Branch, Loop, Random, and Conditional nodes cover every sequencing pattern. Compile to a runtime-ready data asset with one button click.
Input Buffering
Configurable pre-window input buffer stores one input or a full combo queue. Players who press ahead of the window still get smooth continuation, no manual timer management required.
Multiplayer Ready
Melee detection, reaction triggers, and hit pause all replicate correctly on listen and dedicated servers. Initialize with InitializeCombat for players or InitializeCombatForAI for NPCs.
Targeting Subsystem
World subsystem for soft-lock and best-target queries. Pluggable scoring policy, line-of-sight gating, team filtering, and AOE/hitscan/ground query types all ship out of the box.
Damage-Agnostic
Hit detection delivers FCascadeHitData, who hit whom, which tags, which custom values. Your GameplayEffect execution decides the outcome. Cascade never overrides your damage math.
AI Support
UCascadeAIInputAdapter lets NPCs submit combo inputs and activate abilities through the same pipeline as players, no special-casing in ability code.
ICascadeInputAdapter. Getting Started
The fastest path to a working melee character is five steps. All of them can be done in Blueprint; C++ is only needed for Build.cs.
Enable the plugin and add module dependencies
In the Unreal Editor open Edit → Plugins, search for CascadeCombatSystem, and enable it. In your project's Build.cs add "CascadeCombatSystem" and "GameplayAbilities" to PublicDependencyModuleNames.
Replace your AbilitySystemComponent
On your character, swap any existing UAbilitySystemComponent for UCascadeAbilitySystemComponent. It extends the standard GAS component, so existing GAS setup continues to work.
Create a UCascadeCombatSetup data asset
Right-click in the Content Browser and select Cascade → Combat Setup. Add your ability classes to Abilities and map Input Actions to gameplay tags in InputBindings.
Initialize combat on the server
In your character's PossessedBy (server) call InitializeCombat(CombatSetup, EnhancedInputComponent) on the UCascadeAbilitySystemComponent. For AI, call InitializeCombatForAI(CombatSetup) instead.
Build your first combo definition
Right-click in the Content Browser and select Cascade → Combo Definition. Open the asset to launch the graph editor. Add an Ability node, connect it to Root, hit Compile, and assign the definition to a UCascadeCombo ability in your setup asset.
Combo Definition
UCascadeComboDefinition is a data asset that describes a complete combo: its unique tag, the node tree that drives sequencing, activation requirements, and timing. Create one per distinct combo in your Content Browser. The graph editor compiles the visual graph into the node tree at save time.
| Property | Type | Description |
|---|---|---|
| ComboTag | FGameplayTag | Unique identifier for this combo. Used to query and cancel a running combo at runtime. |
| DisplayName | FText | Optional display name for UI or debug output. |
| RootNode | UCascadeComboNode* | Entry point of the combo tree. Set automatically when you compile the graph. |
| GlobalTimeout | float | Seconds of inactivity before the combo auto-resets. Set to 0 to disable. |
| bCanBeInterrupted | bool | Whether higher-priority abilities can cancel this combo mid-chain. |
| ActivationInputTags | TArray<FGameplayTag> | Input tags that activate this combo when received by the ASC. |
| RequiredTagsToStart | FGameplayTagContainer | The owning actor must have all of these tags for the combo to start. |
| BlockedTags | FGameplayTagContainer | Any of these tags on the owner prevents this combo from starting. |
| Priority | int32 | When multiple combos compete, higher priority is evaluated first. |
UCascadeCombo ability
UCascadeCombo is the GAS ability that owns a combo. Assign a UCascadeComboDefinition to its ComboDefinition property and the ability reads all settings from the asset. You can also configure the combo directly on the ability if you prefer not to use a definition asset, set ComboTag, RootNode, and ActivationInputTags directly. UCascadeCombo_Runtime is the variant used when the definition is provided as a spec SourceObject at runtime (e.g. from the Runtime Builder).
Combo Nodes
Each node in the combo graph is a UCascadeComboNode subclass. Nodes evaluate input, gate by conditions, and return the next node to execute. The graph editor represents these as connected boxes; the compiler converts them into the runtime node tree stored in the definition asset.
| Node Class | Purpose |
|---|---|
| UCascadeComboNode_Ability | Activates a TSubclassOf<UGameplayAbility>. The most common node type. Has a GracePeriod (seconds after the ability ends before resetting) and a NextNodes array for continuation. |
| UCascadeComboNode_Branch | Routes to different nodes based on which input tag was received. TMap<FGameplayTag, UCascadeComboNode*> InputBranches maps each input to its destination node. |
| UCascadeComboNode_Conditional | Evaluates gameplay tags on the owner at traversal time. Routes to OnSuccess if RequiredTags are present and BlockedTags are absent, otherwise to OnFailure. Use for airborne-only branches, resource-gated finishers, etc. |
| UCascadeComboNode_Loop | Routes back to a TargetNode up to MaxIterations times. Set MaxIterations to 0 for unlimited looping, useful for sustained-fire or spin attacks. |
| UCascadeComboNode_Random | Picks a child node by weighted probability. Each entry in Children is a FCascadeRandomNodeEntry with a node pointer and weight. Good for variety without explicit branching logic. |
Custom nodes
Subclass UCascadeComboNode in Blueprint or C++ and override EvaluateNode, CanEnterNode, and GetValidNextNodes to implement any traversal logic your game requires.
Runtime & Buffering
UCascadeAbilityTask_RunComboTree is the execution engine for a running combo. It is created internally by UCascadeCombo on activation; you interact with it through UCascadeAbilitySystemComponent rather than directly.
Combo management on UCascadeAbilitySystemComponent
| Function | Description |
|---|---|
| ProcessComboInput(FCascadeComboInputContext) | Route a semantic input to the active combo. Returns true if consumed. Server only. |
| IsComboActive(FGameplayTag) | Returns true if a combo with the given tag is currently running. |
| GetActiveComboInstance(FGameplayTag, FCascadeComboInstance&) | Fills an instance struct with the current step index, active node, and timing data. |
| GetActiveCombos() | Returns all combo tags currently running on this component. |
| EndCombo / EndAllCombos | Ends cleanly, waits for the current ability to finish before resetting. |
| CancelCombo / CancelAllCombos | Immediately cancels the combo and any active ability. |
Input buffering
Set InputBufferDuration (seconds) on the ASC to hold inputs that arrive before a combo window opens. InputBufferMode controls the queue strategy:
| Value | Description |
|---|---|
| SingleInput | One input is stored. A newer input replaces the previous buffered one. |
| FullCombo | The full sequence pressed by the player is queued and replayed in order when the window opens. |
Combo delegates
| Delegate | Signature |
|---|---|
| OnComboStateChanged | (FGameplayTag ComboTag, int32 StepIndex, UCascadeComboNode* CurrentNode) |
| OnComboStepActivated | (FGameplayTag ComboTag, int32 StepIndex, TSubclassOf<UGameplayAbility> AbilityClass) |
| OnComboWindowChanged | (FGameplayTag ComboTag, bool bIsOpen), fires when a combo window opens or closes. |
| OnHitDetected | (const FCascadeHitData&), fires each time the damage window detects a new hit. |
| OnDamageTaken | (const FCascadeHitData&, float DamageAmount), fires on this component's owner when damage is applied. |
Runtime Builder
UCascadeRuntimeComboBuilder lets players customize and assemble combos at runtime, a skill-equip screen where the player picks which abilities fill each combo slot. Load a UCascadeComboTemplate data asset that defines the available slots and per-slot ability tag requirements, fill them via SetSlot, then call BuildCombo to produce a UCascadeComboDefinition that can be registered with the ASC.
| Function | Description |
|---|---|
| LoadTemplate(UCascadeComboTemplate*) | Initialize the builder from a template asset. Resets any in-progress configuration. |
| SetSlot(int32, TSubclassOf<UGameplayAbility>) | Assign an ability to a slot. Returns false if the ability does not satisfy the slot's tag requirements. |
| BuildCombo(FGameplayTag, UObject* Outer) | Produces a UCascadeComboDefinition. Returns nullptr if required slots are empty or validation fails. |
| SaveConfiguration / LoadConfiguration | Serializes slot assignments to/from a FCascadePlayerComboConfig struct for save-game persistence. |
// Build and register a player-assembled combo at runtime
Builder->LoadTemplate(MyComboTemplate);
Builder->SetSlot(0, UMyLightAttack::StaticClass());
Builder->SetSlot(1, UMyHeavyFinisher::StaticClass());
UCascadeComboDefinition* Built =
Builder->BuildCombo(CascadeTags::Combo::Mixed::LLH, this);
if (Built)
{
CascadeASC->RegisterCombo(Built);
} Animation Abilities
UCascadeAnimAbility is the base class for montage-driven abilities. On activation it plays Montage at PlayRate, optionally jumping to MontageSectionName. When the montage completes or is cancelled, the ability ends automatically. UCascadeChargedAbility extends it with hold-to-charge mechanics, accumulates a 0–1 charge percentage between MinChargeTime and MaxChargeTime, fires OnChargeReleased on release.
Both classes are non-damaging by design. Damage is opt-in via composition, your project subclass holds a FCascadeDamageDescriptor BaseDamage field, implements ICascadeHitContextProvider::GetActiveDamageDescriptor, and spawns UCascadeAbilityTask_DamageHandler in the BP graph for per-hit reactions. See the Damage sections below.
| Property | Type | Description |
|---|---|---|
| Montage | UAnimMontage* | The animation to play. Required, the ability will not activate without a valid montage. |
| MontageSectionName | FName | Optional section to jump to on play. Leave empty to start from the beginning. |
| PlayRate | float | Montage playback rate. Default 1.0. |
| bCancelOnMovementInput | bool | When true, movement input exceeding MovementCancelThreshold cancels the ability. Uses UCascadeAbilityTask_WaitMovementInput internally. |
| MovementCancelThreshold | float | Input magnitude [0.0–1.0] above which a cancel is triggered. |
| CancellationSignalTag | FGameplayTag | Gameplay event sent to the owner when the ability is cancelled by movement input. Use to trigger a recovery montage via UCascadeAN_SendGameplayEvent. |
| bUseFlyingModeForRootMotion | bool | Temporarily switches to Flying movement mode to allow Z-axis root motion (launch attacks, uppercuts). |
Override points
| Function | When it fires |
|---|---|
| PlayMontage(Montage, Rate) [BlueprintNativeEvent] | Called to play the montage. Override to play on a secondary mesh or with custom parameters. |
| OnMontageCompleted() | Called when the montage finishes naturally. Base implementation ends the ability. |
| OnMontageCancelled() | Called when the montage is interrupted. Base implementation ends the ability. |
Damage Descriptor
FCascadeDamageDescriptor is the single struct that carries an ability's damage authoring, what GE to apply, magnitude, semantic tags, hit caps, weakspot resolution, project-extensible payload. Abilities that want to deal damage implement ICascadeHitContextProvider::GetActiveDamageDescriptor(WindowTag) and return the descriptor for the active window. Hit producers (notify state, projectile, direct dispatch) call this at hit construction time and stamp the result into FCascadeHitData::SourceDescriptor.
| Property | Type | Description |
|---|---|---|
| DamageEffect | TSubclassOf<UGameplayEffect> | GE applied to the victim on a successful hit. Read by UCascadeAbilitySystemComponent::HandleHitDetected as the default damage applicator, or by your own OnHitDetected listener. |
| Magnitude | float | Surfaced as a SetByCaller named "Magnitude" on the spec, Execution Calculations read it via GetSetByCallerMagnitude(FName("Magnitude"), false, 1.f). |
| HitTags | FGameplayTagContainer | Tags merged into FCascadeHitData::HitTags on every produced hit (Slash, Heavy, Element.Fire, etc). |
| MaxHits | int32 | Total hit cap across all victims. 0 = unlimited. |
| MaxHitsPerTarget | int32 | Per-victim hit cap. 0 = unlimited. |
| GuardBreakEffect / ParryRetaliationEffect | TSubclassOf<UGameplayEffect> | Optional GE overrides, projects route to GuardBreakEffect when the victim is guard-broken, apply ParryRetaliationEffect to the attacker when parried. Empty = no special-case effect. |
| WeakspotResolution | ECascadeWeakspotResolution | How the notify state resolves overlapping weakspots: Ignore / FirstMatch / HighestPriority / MergeAllMatches / BroadcastPerMatch. Default FirstMatch. |
| WeakspotFilter | FGameplayTagQuery | Optional filter, only weakspots whose tags match this query contribute. Empty = all weakspots considered. |
| ProjectPayload | FInstancedStruct | Project extension slot. Derive a USTRUCT from FCascadeDamagePayloadBase with your game's bespoke fields (faction, damage type, knockback magnitude, hit-stop duration, camera shake) and pick it here. Plugin never inspects; project bindings unpack with GetPtr<T>(). |
Per-window overrides
Abilities with multiple distinct hits (combo strings, multi-strike specials) hold a TMap<FGameplayTag, FCascadeDamageDescriptor> keyed by the WindowTag the animator sets on each UCascadeANS_DamageWindow. GetActiveDamageDescriptor(WindowTag) returns the matching override or falls back to the base.
// In your project's UEBAttackAbility
UPROPERTY(EditDefaultsOnly) FCascadeDamageDescriptor BaseDamage;
UPROPERTY(EditDefaultsOnly) TMap<FGameplayTag, FCascadeDamageDescriptor> WindowOverrides;
FCascadeDamageDescriptor GetActiveDamageDescriptor_Implementation(FGameplayTag InWindowTag) const override
{
if (const FCascadeDamageDescriptor* Override = WindowOverrides.Find(InWindowTag))
{
return *Override;
}
return BaseDamage;
} Result payload
Where ProjectPayload is "what the ability is sending," FCascadeHitData::ResultPayload is "what came back." Project's OnHitDetected listener stamps a USTRUCT derived from FCascadeHitResultPayloadBase (applied damage, crit flag, weakspot id, status effects) into this slot. Reactions on the attacker and victim read it.
Damage Handler Task
UCascadeAbilityTask_DamageHandler is the single ability task damage-producing abilities spawn from their BP graph. One handler per ability, it listens for hits the ability produces (whether from a montage notify trace, a projectile collision, or a direct dispatch) and surfaces them as pins for designer-authored reactions. No timing parameters, animator owns timing, ability owns reactions.
| Pin | When it fires |
|---|---|
| OnFirstHit | First time any hit lands. One-shot reactions, camera shake, hitstop request, ability-wide VFX spawn. |
| OnHitResolved | Every resolved hit. FCascadeHitData carries OutcomeTags (Parried/Blocked/Dodged), ResultPayload, and bDirectHit. Branch in BP for per-outcome reactions. |
| OnCancelled | Force-cancelled before any hit fires, owning ability ended, external EndTask. Cleanup hook. |
Direct dispatch (AOE, point-and-click, raycast)
For damage that doesn't come from a continuous trace, the ability gathers targets itself and calls DispatchDirectHit(Target, Descriptor, IdentifierTag) or DispatchDirectHits(Targets[]) on the task. The handler synthesizes FCascadeHitData with bDirectHit=true, runs the same resolution pipeline, and fires the same pins. Reactions branch on bDirectHit before using HitResult.ImpactPoint for decals or surface VFX.
// AOE shockwave at the impact frame of a slam montage
TArray<AActor*> Targets = UEBTargetingHelpers::GetEnemiesInCone(
GetActorLocation(), GetActorForwardVector(), 600.f, 45.f, true);
DamageHandler->DispatchDirectHits(Targets, BaseDamage, EBTags::Window::Shockwave); Resolution Pipeline
Every hit, trace, projectile, or direct dispatch, converges on the same two-phase pipeline on the attacker's ASC. Both delegates pass FCascadeHitData& by mutable reference so listeners can contribute resolution data.
| Phase | Purpose |
|---|---|
| OnPreHitResolve | Authority-side defence phase. Project defence components read SourceDescriptor.ProjectPayload, check victim's GAS tags (Defense.Parrying / Blocking / IFrames), and stamp OutcomeTags (project-owned vocabulary: Outcome.Parried / Blocked / Dodged / Immune). |
| OnHitDetected | Damage application phase. Project's damage router reads SourceDescriptor.DamageEffect, branches on OutcomeTags, applies the GE to the victim, writes ResultPayload (applied damage, crit flag, weakspot id, status effects). |
The plugin's default damage applicator (UCascadeAbilitySystemComponent::HandleHitDetected) provides a working baseline, applies SourceDescriptor.DamageEffect with Magnitude as a SetByCaller. Projects bind their own listener for richer behaviour (faction filtering, damage-type resists, knockback application, status proc rolls, etc).
Other delegates
| Delegate | Side | When it fires |
|---|---|---|
| OnDamageTaken | Victim's ASC | After damage is applied. Carries final FCascadeHitData with both payloads populated. Wire reaction component / VFX / UI here. |
| ApplyHitPause(Attacker, Victim, Duration, TimeDilation) | ASC (BlueprintCallable) | Utility function for freezing both actors briefly. Plugin does not auto-trigger, projects call it from their listener using their own hit-stop config (typically a field on a FCascadeDamagePayloadBase-derived payload). |
Passives
UCascadePassiveAbility is granted and activated automatically by the ASC during GrantCombatAbilities. It does not need an input binding and is never directly activated by the player. Use it for persistent effects, bleed-on-hit procs, damage auras, combo extension bonuses, that live as long as the character has the ability in their spec.
| Event | When it fires |
|---|---|
| OnPassiveActivated [BlueprintImplementableEvent] | When the passive is first granted and activated on the server. Apply persistent GameplayEffects or start timers here. |
| OnHitDetectedPassive(FCascadeHitData) [BlueprintImplementableEvent] | When any hit is detected on the owning ASC. Use for on-hit side effects without modifying the attack ability. |
| OnPassiveDeactivated [BlueprintImplementableEvent] | When the ability is removed or the ASC is shut down. Remove any effects applied in OnPassiveActivated. |
Add passive abilities to the PassiveAbilities array on your UCascadeCombatSetup asset to have them granted automatically on initialization.
Damage Window
UCascadeANS_DamageWindow is the AnimNotifyState that activates hit detection for the duration it is active in the montage. Place it on any frame range where an attack should connect. It polls socket positions each tick, performs swept-volume traces, and broadcasts FCascadeHitData for every new hit, automatically deduplicating within a single swing.
| Property | Type | Description |
|---|---|---|
| bUseWeaponMesh | bool | When true, reads trace configuration from the equipped weapon actor (ACascadeWeaponActor). When false, drives detection from character-mesh sockets using TraceConfig. |
| WeaponAttachSocket | FCascadeSocketName | Which socket on the weapon to use. Only relevant when bUseWeaponMesh is true. |
| TraceConfig | FCascadeWeaponTraceConfig | Hit detection geometry for character-mesh traces. Defines socket segments (FCascadeSocketSegment pairs), trace shape (Line/Box/Sphere/Capsule), and the collision channel. |
| HitTags | FGameplayTagContainer | Tags merged into each hit context produced by this notify. Combined with the ability's HitTags at broadcast time. |
Combo Window
UCascadeANS_ComboWindow marks the frames inside a montage where the combo system accepts the next input. When the notify state begins, it signals the ASC to open the window and replay any buffered input. When it ends, the window closes.
| Property | Type | Description |
|---|---|---|
| WindowOpenTag / WindowCloseTag | FGameplayTag | Gameplay events fired on the owner when the window opens and closes. Use to drive UI indicators. |
| bApplyComboWindowTag | bool | When true, applies ComboWindowActiveTag as a loose gameplay tag for the duration of the window. Useful for gating other abilities or triggering UI state. |
| ComboWindowActiveTag | FGameplayTag | The tag applied while the window is open. Only used when bApplyComboWindowTag is true. |
Other Notifies
Cascade ships several additional notifies that cover common combat patterns without requiring custom ability code.
| Class | Type | Purpose |
|---|---|---|
| UCascadeAN_SendGameplayEvent | Point notify | Sends EventTag to the owner at the exact frame the notify fires. Use to trigger ability phase transitions, sound cues, or Blueprint logic without writing ability code. |
| UCascadeAN_SpawnProjectile | Point notify | Spawns an ACascadeProjectile from a character socket or weapon socket. ECascadeProjectileAimMode controls launch direction: SocketDirection, OwnerForward, CameraTrace, or TargetLocation. |
| UCascadeAN_ApplyDamage | Point notify | Instant forward sphere trace from SocketName that applies damage on contact. Use for quick-and-dirty point attacks that don't warrant a full damage window. |
| UCascadeANS_IFrames | Notify state | Grants invincibility for its duration by applying Cascade.State.Invulnerable. Optionally also applies Cascade.State.Dodging and any extra tags via AdditionalTags. |
| UCascadeANS_TargetStick | Notify state | Snaps the attacker toward the locked target, then holds the distance for the notify duration. Configurable snap speed, hold speed, and reacquire-on-loss. Keeps melee attacks connected without relying on root motion precision. |
| UCascadeANS_DragTarget | Notify state | Moves the target actor alongside the attacker. Three modes: FollowSocket lerps to a socket, CurveOffset drives from a UCurveVector, LaunchAndReturn launches the target then pulls it back with ReturnImpulse. |
Weapons
ACascadeWeaponActor is the base class for any weapon that participates in Cascade hit detection. It implements ICascadeTraceConfigProvider so UCascadeANS_DamageWindow can read socket positions from the weapon mesh directly. Attach it to a character socket; call DrawWeapon() and SheathWeapon() to transition states, the weapon re-attaches to DrawnSocket or SheathSocket automatically.
| Property | Type | Description |
|---|---|---|
| TraceConfig | FCascadeWeaponTraceConfig | Defines the swept geometry for hit detection. Contains TraceSegments (socket-pair definitions), TraceShape (Line/Box/Sphere/Capsule), radius/extent values, and collision channel. |
| DrawnSocket / SheathSocket | FName | Character sockets to attach to when drawn and sheathed. |
| ProjectileSpawnSockets | TArray<FCascadeSocketName> | Named sockets used as projectile spawn origins by UCascadeAN_SpawnProjectile when bSpawnFromWeapon is true. |
| CombatSetup | UCascadeCombatSetup* | Optional. Grants its abilities to the character's ASC when drawn, revokes them when sheathed. |
| EquipEffect | TSubclassOf<UGameplayEffect> | Optional GameplayEffect applied while the weapon is drawn, stat bonuses, passive auras. |
Finding the active weapon
// Get the currently drawn weapon on any actor
ACascadeWeaponActor* Weapon =
ACascadeWeaponActor::FindDrawnWeapon(Character);
// Retrieve just the mesh for socket queries
UMeshComponent* Mesh =
ACascadeWeaponActor::FindDrawnWeaponComponent(Character); Projectiles
ACascadeProjectile is the base actor for ranged attacks. Spawn it from UCascadeAN_SpawnProjectile or from an ability directly. Call InitializeProjectile(CascadeASC, SourceAbility, HitTags) after spawning so the owning ASC receives FCascadeHitData on impact. Movement behavior is a swappable UCascadeProjectileMovementStrategy, set MovementStrategyClass on the projectile to choose one.
| Property | Type | Description |
|---|---|---|
| CollisionRadius | float | Sphere collision radius in cm. |
| PierceCount | int32 | Additional actors the projectile passes through after the first hit. 0 destroys on first contact. |
| bDestroyOnEnvironmentHit | bool | Destroy the projectile when it hits world geometry. |
| Lifetime | float | Auto-destroy timer in seconds. Set to 0 to disable. |
| MovementStrategyClass | TSubclassOf<UCascadeProjectileMovementStrategy> | Movement strategy to instantiate on spawn. Leave null to use the built-in UProjectileMovementComponent. |
Movement strategies
| Class | Key Properties | Purpose |
|---|---|---|
| UCascadeProjectileMovementStrategy_Homing | Speed, MaxTurnRateDegrees, TargetSocketName | Steers continuously toward a tracked actor or location. Guided missiles, seeking arrows. |
| UCascadeProjectileMovementStrategy_Bezier | TravelDuration, P1Offset, P2Offset | Follows a cubic Bezier arc to a destination. Lobbed grenades, mortars, parabolic arrows. |
| UCascadeProjectileMovementStrategy_Boomerang | MaxRange, OutboundSpeed, ReturnSpeed, ReturnThreshold | Flies outward to MaxRange then reverses. Thrown weapons, chakrams, returning axes. |
Targeting
The targeting system has two layers. UCascadeTargetingSubsystem is a world subsystem for soft-lock management, it scores candidates by angle and distance and can hold a locked target across frames. UCascadeTargetingQuery subclasses are GAS-integrated query objects used inside abilities to resolve target data for a single activation.
UCascadeTargetingSubsystem
| Function | Description |
|---|---|
| FindBestTarget(FCascadeTargetingRequest) | Scores all ICascadeTargetable actors in range and returns the best candidate. Respects LOS, angle cap, and team filter. |
| SetTargetingMode(ECascadeTargetingMode, AActor*) | Switch between Unlocked (best target per call) and Locked (sticky soft-lock on a specific actor). |
| GetLockedTarget() | Returns the currently locked actor, or nullptr when Unlocked. |
| BuildRequestFromProfile(Owner, Origin, Profile) | Builds a FCascadeTargetingRequest from a UCascadeTargetingProfile data asset. The profile stores range, angle, distance/angle weights, and scoring policy class. |
Targeting queries (in abilities)
Assign a query to UCascadeAbilityTask_WaitTargetData in an ability. The task calls OnTargetDataReady when the query resolves, or OnTargetingCancelled if cancelled.
| Query Class | Purpose |
|---|---|
| UCascadeTargetingQuery_Hitscan | Camera-space sweep to the first actor with an ASC. For hitscan guns or lock-on confirmation. |
| UCascadeTargetingQuery_AOE | Sphere overlap centered on the avatar. Returns up to MaxTargets actors. For ground-pounds, explosions. |
| UCascadeTargetingQuery_GroundLocation | Traces down from the camera to find a surface point. Optional grid snap. For placement abilities. |
| UCascadeTargetingQuery_SingleActor | Resolves one actor via the subsystem's locked target or a camera trace. Mode set via ECascadeSingleActorQueryMode: Subsystem or CameraTrace. |
| UCascadeTargetingQuery_Self | Returns the ability owner's avatar. For self-cast abilities. |
Making an actor targetable
Implement ICascadeTargetable on any actor that should appear in targeting results:
FVector GetTargetPoint_Implementation() override
{
// Return the world position used for scoring (e.g. chest bone)
return GetMesh()->GetSocketLocation(FName("spine_03"));
}
bool IsTargetable_Implementation() override
{
return !IsDead();
} Weakspots
Weakspots are shape components placed on the victim's mesh that contribute tags to hits that land inside them. Used for headshots, armor breaks, exposed cores on big enemies, and lock-on regions. The notify state's WeakspotResolution (on the descriptor) controls how overlapping matches are resolved.
| Class | Role |
|---|---|
| UCascadeTargetableComponent | Aggregator on the victim, holds the replicated bIsTargetable flag, the primary target point (socket + offset), and the registry of weakspot components on this actor. Required for any weakspot to function. Companion UCascadeTargetingHelpers Blueprint library exposes IsTargetable / GetPrimaryPoint queries. |
| UCascadeWeakspotSphere / Box / Capsule | Shape-based weakspot subclasses. Each derives from the engine's native shape component (USphereComponent / UBoxComponent / UCapsuleComponent) so designers get viewport gizmos natively. Implements ICascadeWeakspotProvider for shape-specific point containment. Self-registers with the owner's UCascadeTargetableComponent on register. Active state replicates per-component. |
FCascadeWeakspotData
Static metadata struct authored on each weakspot component. Identifier (FName), tags (merged into HitData.HitTags on match), priority (drives HighestPriority resolution and lock-on ordering), bDefaultActive, bDestroyOnHit (auto-deactivates on first match), bIsLockOnTarget (eligible for lock-on cycling).
Lock-on cycling
Big enemies with multiple lock-on-eligible weakspots support region cycling. UCascadeTargetingSubsystem::SetLockedRegion(FName) / CycleLockedRegion(int32) / GetLockedActorRegions() drive selection. OnLockedRegionChanged delegate fires for HUD updates. The LockedActorRegion query mode on UCascadeTargetingQuery_SingleActor returns the locked weakspot's world location for ability aiming.
Reactions
The reaction system decouples visual hit feedback from ability code. UCascadeReactionComponent lives on any actor that needs to respond to being hit or killed. It receives replicated hit and death triggers, evaluates a priority-sorted list of handlers from a UCascadeReactionSetup data asset, and executes the first handler whose tag conditions are met.
UCascadeReactionSetup (Data Asset)
| Property | Type | Description |
|---|---|---|
| HitHandlers | TArray<UCascadeReactionHandler*> | Handlers evaluated in priority order when a hit reaction is triggered. |
| DeathHandlers | TArray<UCascadeReactionHandler*> | Handlers evaluated on death, typically a ragdoll entry and a death montage variant. |
| GlobalHitReactionCooldown | float | Minimum seconds between consecutive hit reactions on this actor. Prevents reaction spam on rapid hits. |
| bRagdollOnDeath / bDisableCollisionOnDeath | bool | Common death behaviors available as first-class settings. No custom handler needed for basic ragdoll deaths. |
UCascadeReactionHandler_Montage
The built-in UCascadeReactionHandler_Montage covers the common reaction case: it plays an animation (with optional directional variants for front/back/left/right), spawns a Niagara VFX, plays a sound, and fires a gameplay cue, all configured in the data asset, no code. Subclass UCascadeReactionHandler for custom reaction logic, overriding CanHandle and Execute.
| Property on any handler | Description |
|---|---|
| RequiredTags / BlockedTags | Tag gate on the incoming FCascadeHitData. Handler only evaluates if RequiredTags are present and none of BlockedTags match. |
| Priority | Higher priority handlers are evaluated first. First match wins. |
| bInterruptCurrentReaction | Whether this handler preempts a currently playing reaction. |
| CooldownAfter | Per-handler cooldown in seconds after execution. |
Movement Bridge
Cascade is movement-system-agnostic. Plugin features that need to read or manipulate the avatar's movement state, anim flying-mode toggle, drag-target freeze, gravity-scale GE, airborne tag, cancel-on-input, directional input adapter, call through ICascadeMovementBridge. Projects supply a bridge component implementing the interface; the ASC discovers it on InitAbilityActorInfo.
| Method | Purpose |
|---|---|
| GetMovementInputVector() | Player's movement intent this frame, world-space. Drives cancel-on-input and directional combos. |
| GetIntendedFacingYaw() | Yaw of the avatar's intended facing. Used by directional input adapter for movement-relative tags. CMC returns control rotation; Mover returns GetTargetOrientation().Yaw. |
| GetMovementModeTag() / IsAirborne() | Current mode as a Cascade.Movement.* tag, Walking, Falling, Flying, Swimming, Frozen, Custom. |
| SetMovementMode(Tag) | Switch mode by tag. Used by anim abilities for Z-axis root motion (SetMovementMode(Cascade.Movement.Flying)). |
| FreezeMovement() / RestoreMovement() | Capture and restore the avatar's mode, used by UCascadeANS_DragTarget to suspend the victim during a drag. |
| GetGravityScale() / SetGravityScale(scale) | Read / write gravity scale factor (1.0 = world default). Used by UCascadeGEComponent_GravityScale for knock-up effects. |
| GetMovementModeChangedDelegate() | Multicast that fires on mode transitions. ASC's airborne-tag tracker subscribes here. |
Discovery
The ASC's InitAbilityActorInfo walks the avatar (the actor first, then its components) for any ICascadeMovementBridge implementer and caches it as a TScriptInterface. Project code on actors without an ASC uses CascadeMovementBridge::FindOnActor(InActor).
UCascadeDefaultMovementBridge (CMC)
Plugin-shipped UActorComponent implementing the interface against UCharacterMovementComponent. Add it to any ACharacter avatar to use Cascade out of the box on a CMC pawn. Maps Cascade.Movement.* tags to EMovementMode values, rebroadcasts ACharacter::MovementModeChangedDelegate.
Project bridges
Projects on Mover, GMC, or custom systems ship their own bridge component. Mover example: maps Cascade.Movement.* tags to Mover's DefaultModeNames via QueueNextMode, reads input from the Mover input collection, translates SetGravityScale to SetGravityOverride. Plugin doesn't depend on the Mover module, that stays project-side.
Input
Cascade routes all input through the ICascadeInputAdapter interface, decoupling the source of input from combo and ability execution. The default implementation is UCascadeEnhancedInputAdapter for players. For AI, use UCascadeAIInputAdapter. Implement the interface yourself to support any custom input source.
UCascadeEnhancedInputAdapter (player)
Set up automatically when you call InitializeCombat(Setup, EnhancedInputComponent). You can also register actions individually:
| Function | Description |
|---|---|
| RegisterInputAction(UInputAction*, FGameplayTag) | Bind a physical UInputAction to a semantic gameplay tag. When the action fires, the tag is submitted to the ASC as a FCascadeComboInputContext. |
| RegisterMappingConfig(UCascadeInputMappingConfig*) | Batch-register all mappings from a UCascadeInputMappingConfig data asset. Preferred over individual RegisterInputAction calls. |
| SetTriggerEvents(ETriggerEvent, ETriggerEvent) | Override which Enhanced Input trigger event counts as start and end of an input. Default is Started / Completed. |
UCascadeAIInputAdapter (AI)
Registered when you call InitializeCombatForAI(Setup). Drive abilities directly from behavior tree tasks:
// Submit a combo input from an AI behavior tree task
UCascadeAIInputAdapter* Adapter = CascadeASC->GetAIInputAdapter();
Adapter->RequestComboInput(CascadeTags::Attack::Light, {});
// Activate a standalone ability directly
Adapter->RequestAbilityInput(SpecHandle); Gameplay Tags
Cascade registers its tag namespace automatically. All native tags are declared in CascadeGameplayTags.h and accessible as CascadeTags:: in C++.
| Group | Examples | Used for |
|---|---|---|
| Cascade.State | Dead, Attacking, ComboWindow, Dodging, Airborne, Dragged, Invulnerable | Transient tags applied and removed by the plugin. Gate ability activation and target eligibility on these. |
| Cascade.Ability | Attack.Light, Attack.Heavy, Attack.Aerial, Defense.Dodge, Movement.Jump | Ability classification. Applied as ability tags and used in Conditional node tag gates. |
| Cascade.Combo | LightAttack.ThreeHit, HeavyAttack.TwoHit, Mixed.LLH | Combo identifier tags for the built-in demo definitions. Use as ComboTag on your own definitions. |
| Cascade.Event | Combo.WindowOpened, Combo.Completed, Hit.Landed, Death.Died | Gameplay events dispatched by the plugin. Bind to these in abilities or Blueprint to react to combat milestones. |
| Cascade.Damage | Physical.Slash, Physical.Pierce, Elemental.Fire, True | Hit classification. Add to attack abilities; read in your damage execution to apply armor, elemental reactions, etc. |
| Cascade.Effect | Stun, Knockback, Launch, Bleed, Burn, Freeze | Status effect tags. Apply via GameplayEffects from your execution; reaction handlers can gate on these. |
| Cascade.GameplayCue | Hit.Heavy, Hit.Critical, Combo.Finisher, Impact.Metal | Cue tags fired by reaction handlers. Map to Niagara effects and sound assets in your GameplayCue manager. |
| Cascade.Movement | Walking, Falling, Flying, Swimming, Frozen, Custom | Movement-mode vocabulary used by ICascadeMovementBridge::GetMovementModeTag / SetMovementMode. Plugin features compare against these; project bridges may return their own tags for native modes not in this set. |
| Cascade.Cheat | GodMode, DemigodMode | Applied by cheat commands. Check for these in your damage execution to skip damage. |
Debug Tools
Cascade includes debug utilities gated behind CVars and compile-time conditions. None require manual stripping for shipping builds.
| Tool | How to use |
|---|---|
| Trace previews | Editor-side preview shapes on UCascadeANS_DamageWindow show the swept volume at design time. Runtime trace drawing is controlled by a CVar on the notify. |
| UCascadeDebugHelpers | Blueprint function library: DrawComboTree renders a combo definition as a 2D graph on screen, LogComboInfo prints the tree, DrawAttackRange visualizes a radius in the world. |
| UCascadeComboHelpers | Runtime query library for UI blueprints: IsComboActive, GetCurrentComboStep, GetActiveCombos, and GetCascadeASC from any actor reference. |
| Cheat commands | CascadeGodMode applies Cascade.Cheat.GodMode (block all damage). CascadeDemigod applies Cascade.Cheat.DemigodMode (block damage that would kill). |
| Gameplay Debugger, CascadeTargeting | Press ' in PIE and enable the CascadeTargeting category. Auto-focuses on the actor under the camera; renders its targetable flag, primary point, every registered weakspot (with state, identifier, priority, tags, dimensions), and the currently locked region. Server-replicated text and shapes so dedicated-server runs show authoritative state. |
| Visual Logger | Combo steps, hit detection events, and reaction triggers are logged for timeline-based replay. Open Window → Visual Logger in-editor and filter by Cascade. |
Replication
Cascade is server-authoritative. All combat decisions, hit detection, combo progression, ability activation, happen on the server. Below is a summary of each system's replication model.
| System | Replication model |
|---|---|
| Ability activation | Standard GAS prediction. Client-side prediction is available through the standard GAS prediction flow. No extra setup needed beyond standard GAS. |
| Hit detection | UCascadeANS_DamageWindow runs on the server only. Clients do not sweep traces. Hit feedback is driven by the reaction component's Multicast RPCs. |
| Reaction triggers | UCascadeReactionComponent fires Multicast_TriggerHitReaction and Multicast_TriggerDeathReaction as reliable NetMulticast RPCs. All clients play the reaction simultaneously. |
| Hit pause | ApplyHitPause(Attacker, Victim, Duration, TimeDilation) manages time dilation server-side. The effect reaches clients via the standard replicated CustomTimeDilation property. |
| Combo state | Lives server-side on the ASC. Not replicated to clients directly. Use the ASC delegates on the server or respond to replicated gameplay events on clients. |
| Player input | UCascadeEnhancedInputAdapter routes input through GAS activation events with client-side prediction. Combo continuation uses the standard GAS ability task prediction window. |
| AI input | UCascadeAIInputAdapter runs server-side only. No prediction needed for NPC-driven actions. |
InitializeCombat from PossessedBy on the server and bind input from SetupPlayerInputComponent on the client. Both must run before the player can trigger abilities, the ASC coordinates the two through standard GAS cross-machine flow.