toamig.com / Plugins / Cascade Combat System Get on Fab

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.

v0.3

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.

Cascade Combat System requires Gameplay Ability System (GAS). Enhanced Input is the default player integration, but any input source is supported by implementing 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.

1

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.

2

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.

3

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.

4

Initialize combat on the server

In your character's PossessedBy (server) call InitializeCombat(CombatSetup, EnhancedInputComponent) on the UCascadeAbilitySystemComponent. For AI, call InitializeCombatForAI(CombatSetup) instead.

5

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.

PropertyTypeDescription
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 ClassPurpose
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

FunctionDescription
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:

ValueDescription
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

DelegateSignature
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.

FunctionDescription
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.
C++
// 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.

PropertyTypeDescription
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

FunctionWhen 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.

PropertyTypeDescription
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.

C++
// 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.

PinWhen 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.

C++
// 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.

PhasePurpose
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

DelegateSideWhen 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.

EventWhen 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.

PropertyTypeDescription
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.
Set the notify to BranchingPoint tick type for frame-accurate hit detection on dedicated servers. Editor preview shapes are drawn at design time and can be toggled via CVars at runtime.

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.

PropertyTypeDescription
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.

ClassTypePurpose
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.

PropertyTypeDescription
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

C++
// 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.

PropertyTypeDescription
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

ClassKey PropertiesPurpose
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

FunctionDescription
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 ClassPurpose
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:

C++
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.

ClassRole
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)

PropertyTypeDescription
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 handlerDescription
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.

MethodPurpose
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:

FunctionDescription
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:

C++
// 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++.

GroupExamplesUsed 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.

ToolHow 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.

SystemReplication 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.
Call 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.