Weapons · Updated May 14, 2026

Weapon Hit FX

Weapon Hit FX


#Overview

Impact effects run on two separate paths:

PathWho sees itWhenHow
PredictedOwning client onlyImmediately on fireDirect Niagara spawn in the fire ability BP
ConfirmedAll other clientsAfter server validatesImpactCueTag Gameplay Cue multicast by GAS

The owning client gets zero-latency feedback by spawning impacts directly in the Local Predicted fire ability BP — no round-trip needed. All other clients see the confirmed impact via the GAS cue.


#Data

#ImpactCueTag on FSLWeaponFireMode


ImpactCueTag = GameplayCues.Weapon.AssaultRifle.Impact

Set per fire mode on the weapon data asset. Must begin with GameplayCues.. Leave blank to disable impact cues for that fire mode.

#FSLShotInfo — confirmed hit fields (filled by server)

FieldTypeDescription
HitLocationFVectorWorld-space impact point
HitNormalFVectorSurface normal at impact
bHitPawnbooltrue = pawn hit (damage applied), false = environment

These are empty on the way up (client → server) and filled by Server_ProcessShots before multicasting.


#Server Flow

Server_ProcessShots traces using ECC_Visibility (hits both pawns and world geometry):

  • Hit actor is a pawn → ApplyPointDamage called, bHitPawn = true
  • Hit actor is world geometry → no damage, bHitPawn = false
  • Either way → ExecuteGameplayCue(ImpactCueTag, CueParams{ImpactPoint, ImpactNormal}) fired on authority, GAS multicasts to all clients
  • Shot added to ConfirmedShotsMulticast_OnShotsConfirmedOnShotsConfirmed BP event

Shots that miss everything produce no cue and no confirmed shot.


#Path 1 — Predicted Impact (owning client + listen server host)

The fire ability is Local Predicted — it runs on the owning client immediately. The client already has the local FHitResult from its own trace. On the listen server host the authoritative trace produces the same hit, and OnProjectileHitPredicted is called there too (the ImpactCueTag cue skips locally controlled pawns, so this is the only impact path for the host player). Spawn the impact effect directly in the fire ability BP:


[Fire ability BP — local predicted execution]

│

├── Line trace → LocalHit

│

├── [IsValid(LocalHit)] →

│     Spawn Niagara at LocalHit.ImpactPoint, oriented by LocalHit.ImpactNormal

│     Play local impact sound

│

└── Collect FSLShotInfo for this pellet → flushed once per trigger pull via QueueShotsForValidation

No component event, no delegate, no round-trip. The Local Predicted policy gives this for free.


#Path 2 — Confirmed Impact (all clients)

Create a GameplayCueNotify_Burst Blueprint named GC_SL_<WeaponName>_Impact and set its tag to match ImpactCueTag.

#Cue Blueprint


Event OnExecute (MyTarget, Parameters)

│

├── Branch: Parameters.Instigator → IsLocallyControlled

│     True  → Return  (owning client already played a predicted impact — skip)

│     False → continue

│

├── Spawn Niagara System

│     Location: Parameters.Location

│     Rotation: MakeRotFromZ(Parameters.Normal)

│

└── Play Sound at Location: Parameters.Location

The IsLocallyControlled guard prevents the owning client from seeing the impact twice (once predicted, once confirmed).

#Data Asset Setup

FieldValue
FireCueTagGameplayCues.Weapon.<WeaponName>.<FireMode> — muzzle flash / fire sound
ImpactCueTagGameplayCues.Weapon.<WeaponName>.Impact — bullet hole / surface impact

Both tags must be added to Project Settings → GameplayTags and have matching GC_ Blueprint assets under the Cue Manager scan path.


#Adding Impact FX for a New Weapon

  1. Add tag GameplayCues.Weapon.<WeaponName>.Impact in Project Settings → GameplayTags
  1. Create GC_SL_<WeaponName>_Impact (GameplayCueNotify_Burst) — set its Gameplay Cue Tag to the new tag
  1. Wire the cue BP per the template above
  1. Set ImpactCueTag on the weapon's FSLWeaponFireMode in the data asset
  1. In the fire ability BP, spawn a predicted impact locally using the local trace FHitResult