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, …):
- Open the animation.
- Curves → Add Curve (float) → name it
DisableLHIK(exact name, reused across clips).
- 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:
- Get Curve Value — Curve Name =
DisableLHIK. Target defaults to self. (Thread-safe.)
- Less (<) (float) — A = curve value, B = 0.5. True when the curve is below
threshold, i.e. melee anim is NOT playing.
- AND Boolean — inputs: existing
Should Apply LHIK, and the<result.
- Wire the AND output into the
Active Valuepin of Blend Poses by bool
(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 onMC_TP_AR_Melee2).Get Curve Valuereturns 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):
- Ramp the
DisableLHIKcurve from 1 → 0 over the recovery frames of the clip.
- Replace Blend Poses by bool with a float/alpha blend node.
- Feed
1 - DisableLHIK(aOneMinus/subtract) — optionally `× ShouldApplyLHIK as
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.
#Related
Docs/Melee.md— melee ability,MeleeSwingDuration,bIsMeleeingsnapshot.
Docs/WeaponClipping.md— FP weapon obstruction / pull-back (separate system).