Weapons · Updated Jun 16, 2026

Left-Hand IK (LHIK) — Melee Suppression

Left-Hand IK (LHIK) — Melee Suppression

How the FP weapon-layer left-hand IK is gated so it does not apply while a melee animation is playing.

#The problem

LHIK is driven by a Should Apply LHIK bool feeding the Active Value of a Blend Poses by bool node:

  • True Pose → FABRIK weapon IK applied (hand snapped to the weapon grip socket).
  • False Pose → cached non-IK pose.

We also want LHIK off while a melee swing animates. The obvious signal — bIsMeleeing — is wrong for this: that bool is tied to MeleeSwingDuration (0.6s, the GAS Meleeing tag lifetime), but the melee animation asset plays longer than 0.6s. Gating on !bIsMeleeing snaps LHIK back on mid-swing.

Melee here is not a montage — it's a state-machine state (the "Melee" state) playing a non-looping clip (MC_Rifle_Melee, MC_Pistol_Melee, etc.), so Is Any Montage Playing does not apply either.

#The fix — a curve baked on the melee anim

Drive the suppression off the animation asset's own timeline, not the tag.

#1. Author the curve (per melee clip)

Only the two-handed main weapons need this — rifle and shotgun, where the left hand
grips the foregrip via FABRIK and must release during a bash. The **pistol is the sidearm,
held one-handed in the left hand → it has no LHIK**, so its melee clips
(MC_FP_Pistol_Melee, MC_TP_Pistol_Melee) do not get this curve.

For every FP melee animation that plays through a weapon layer that uses left-hand foregrip IK (MC_Rifle_Melee, MC_Shotgun_Melee, …):

  1. Open the animation.
  1. Curves → Add Curve (float) → name it DisableLHIK (exact name, reused across clips).
  1. Set it to 1.0 across the whole clip.
    • Optional: ramp 1 → 0 over the recovery frames if you want the hand to return to
    • the weapon before the clip fully ends.

If an LHIK-using weapon's melee clip is missing the curve, LHIK snaps the off-hand to the
grip mid-swing. Add it to all the rifle/shotgun melee clips.

Because curves are evaluated through the pose with blend weights, the value reads ~1 while the Melee state dominates and ramps to 0 as it blends out — a natural fade, and exactly as long as the clip plays. No dependence on the 0.6s tag window.

#2. Wire it into Should Apply LHIK


[Get Curve Value]                [Less (<)]

  Curve Name: DisableLHIK  ──►  A         ──►┐

                                B: 0.5        │

                                              ├──►[AND Boolean]──►[Active Value]

[Should Apply LHIK] ──────────────────────────┘   (of Blend Poses by bool)

Node-by-node:

  1. Get Curve Value — Curve Name = DisableLHIK. Target defaults to self. (Thread-safe.)
  1. Less (<) (float) — A = curve value, B = 0.5. True when the curve is below
  2. threshold, i.e. melee anim is NOT playing.

  1. AND Boolean — inputs: existing Should Apply LHIK, and the < result.
  1. Wire the AND output into the Active Value pin of Blend Poses by bool
  2. (replacing the current direct connection).

Net: LHIK applies only when the original condition is true and the melee curve is inactive.

#Where to put the nodes — call Get Curve Value in Thread Safe Update Animation

Do this in the Blueprint Thread Safe Update Animation function, not inline in the AnimGraph / an Animation Layer. Read the curve there into a bool variable, then have the AnimGraph's Active Value pin read that variable:


(Thread Safe Update Animation)

  bShouldApplyLHIK = (existing logic) AND (GetCurveValue('DisableLHIK') < 0.5)

(AnimGraph)

  Active Value  ◄── bShouldApplyLHIK

Gotcha (cost us a session, 2026-06-13): calling Get Curve Value inline in the
AnimGraph or an Animation Layer returned 0 every frame even with the curve correctly
authored (flat 1.0 on MC_TP_AR_Melee2). Get Curve Value returns the curve from the
instance's evaluated pose; reading it from Thread Safe Update Animation and caching to
a bool is the path that reliably works. Switching to that fixed it immediately.

#Optional — smooth blend instead of binary

To ease LHIK back in during swing recovery (no pop):

  1. Ramp the DisableLHIK curve from 1 → 0 over the recovery frames of the clip.
  1. Replace Blend Poses by bool with a float/alpha blend node.
  1. Feed 1 - DisableLHIK (a OneMinus/subtract) — optionally `× ShouldApplyLHIK as
  2. float` — into the blend alpha.

#Why not the alternatives

  • AnimNotifyState across the clip → thread-safe bool — works, asset-authored, but
  • binary (no blend) and more plumbing.

  • State weight query — melee is a state, but cross-referencing its weight from the
  • IK section needs a state-machine ref + index lookup that breaks if states are reordered. The curve avoids that fragility and blends for free.

  • Docs/Melee.md — melee ability, MeleeSwingDuration, bIsMeleeing snapshot.
  • Docs/WeaponClipping.md — FP weapon obstruction / pull-back (separate system).