LyraStarterGame Weapon System
This is an overview of the Weapon System in LyraStarterGame.
A Lyra weapon is a specialized piece of equipment based on the Lyra Equipment System, which itself is based on the Lyra Inventory System. Make sure you are familiar with those concepts as well.
Weapon Concepts
- Weapon Instance
- Derived from Equipment Instance
- Adds Equipped/Unequipped Anim Sets
- Ranged Weapon Instance
- Derived from Weapon Instance
- Adds logic RE shooting a projectile at range, ammunition capacity and use, etc
- Weapon State Component (Controller Component)
- Manages equipped weapon ticking and player feedback (hit result visualization)
- Weapon Debug Settings
- Developer debug helper
- Weapon Spawner (Actor)
- Spawn Weapons at dedicated spawning pads in the world
Related Gameplay Abilities
- Melee Attack Ability
- Used for all melee attacks regardless of the weapon type
- Ranged Weapon Base Ability
- Base ability for all ranged weapons
Weapon Instance
A Weapon Instance (ULyraWeaponInstance
) is an
Equipment Instance
that also has equipped and unequipped animation sets associated with it.
It also keeps track of how long it has been since the player last interacted with it.
Most of the implementation is in the BP B_WeaponInstance_Base
, from which all other Lyra
Weapon Instances are derived:
B_WeaponInstance_Pistol
B_WeaponInstance_Rifle
B_WeaponInstance_Shotgun
B_WeaponInstance_NetShooter
(prototype)
The Weapon Instance has a Tick()
method, which is executed every tick if/when the weapon
is equipped by the Pawn. This ticking is managed by the
Pawn Controller’s Weapon State Component.
Ranged Weapon Instance
A Ranged Weapon Instance is derived from Weapon Instance and implements ILyraAbilitySourceInterface
.
It adds the concept of bullets, shot accuracy and spread, etc.
Weapon State Component
ULyraWeaponStateComponent
goes on the Pawn Controller.
This component:
- Is responsible for making the Pawn’s currently equipped weapon
Tick()
- During Targeting:
- Keeps track of weapon “hit markers” for the local player
- e.g. so you can see bullets actually hit their targets (if they do hit something)
- Keeps track of weapon “hit markers” for the local player
- When server processes TargetData:
- Remembers the “hit markers” that actually resulted in valid hits
- Makes these available to
SHitMarkerConfirmationWidget
to draw the hit markers on the player’s screen
- Makes these available to
- Remembers the “hit markers” that actually resulted in valid hits
Weapon Debug Settings
ULyraWeaponDebugSettings
is an implementation of a new UE5 feature, UDeveloperSettingsBackedByCVars
.
Definitely read this class if you want to have similar functionality in your game, which I recommend since this makes gameplay debugging significantly easier.
Lyra supports the option to compile out weapon debugging, good for production. When developing a ranged weapon you should absolutely turn these debugging features on unless you like to needlessly waste your own time.
Weapon Spawner
This is a pad with a fixed position that spawns weapons based on the Weapon Definition you configure it for. You can set Cooldown time, the mesh of the weapon to show that will be picked up, etc.
This C++ class is implemented such that the core functionality of actually giving the weapon to the pawn MUST be implemented in Blueprints. There are 2 BP implementations:
B_WeaponSpawner
- ShooterCore pads that give weapons and health pickups
B_AbilitySpawner
- ShooterCore proximity HOT/DOT pads
- Based on
B_WeaponSpawner
but doesn’t actually grant weapons
Melee Attack Ability
GA_Melee
is the Melee Attack Ability, derived from GA_AbilityWithWidget
, which itself is
based on ULyraGameplayAbility
.
It is implemented such that it can be executed regardless
of the type of weapon equipped, provided that weapon derives from B_WeaponInstance_Base
(BP constraint).
Note that this ability is not derived from
the base Equipment Ability (ULyraGameplayAbility_FromEquipment
). While this makes sense
in that equipment isn’t necessarily required to melee (Pawns have fists, feet, heads, etc),
it also means that in the current implementation there is no way to make a Katana melee
for more than a fist. This seems like a significant implementation flaw. You should absolutely
change this if you want interesting melee gameplay.
On Melee Attack:
- Play Melee Attack Animation Montage (configurable per weapon)
- If Authority:
- If all of these conditions are true:
- If a Pawn in front of the Attacker was hit (limited by BP to 1 hit maximum)
- If the hit Pawn is on a different team than the Attacker (BP constraint)
- If the hit Pawn is not behind a wall or other obstacle
- Then:
- Apply additive Root Motion Force in the Attacker’s forward direction based on
Strength
parameter of Melee attack (constant regardless of weapon) - Add Gameplay Effect to hit Pawn:
GE_Damage_Melee
(constant regardless of weapon) - Execute GameplayCue on Attacker:
GameplayCue.Weapon.Melee.Hit
- Play Melee Impact sound at world impact location
- Apply additive Root Motion Force in the Attacker’s forward direction based on
- If all of these conditions are true:
Ranged Weapon Base Ability
ULyraGameplayAbility_RangedWeapon
derives from the Equipment System’s
Equipment Ability
(ULyraGameplayAbility_FromEquipment
), giving it easy access to the specific weapon that
is responsible for granting the ability to the player, which will be equipped at the time
of ability activation.
This is the base class for all Lyra Ranged Weapons, and is implemented by:
GA_Weapon_Fire
GA_Weapon_Fire_Pistol
GA_Weapon_Fire_Rifle_Auto
GA_Weapon_Fire_Shotgun
GA_WeaponNetShooter
(prototype)
As seems to be the standard for Lyra Gameplay Abilities, very little is done in C++ and
most of the implementation is in the BP, in this case GA_Weapon_Fire
which is the base
BP for ranged weapons.
If you’re interested in how weapons work in Lyra, definitely study the event graph of
GA_Weapon_Fire
to see how it works.
On Ability Activation (on firing the weapon):
- If locally controlled pawn:
- Generate TargetData based on where the weapon is aiming
- See
ULyraGameplayAbility_RangedWeapon
::PerformLocalTargeting
- See
- If remote client:
- Send TargetData RPC to server
- Generate TargetData based on where the weapon is aiming
- Play weapon firing animation
- Send Gameplay Cue to weapon owner:
GameplayCue.Weapon.Rifle.Fire
- Send Gameplay Cue to each target hit:
GameplayCue.Weapon.Rifle.Impact
- If Authority:
- Spawn physics field actor at each target hit (if the weapon has physics field impact configured)
- Add Gameplay Effect to each target hit
- The effect varies by weapon, for example:
GE_Damage_Pistol
- The effect varies by weapon, for example:
Additionally, ranged weapons will listen for “failed to fire weapon” Gameplay Events
(Ability.PlayMontageOnActivateFail.Message
)
and play an animation montage to help the player visualize the failed ability activation.
That Gameplay Message is broadcast by the base ULyraGameplayAbility
::NativeOnAbilityFailedToActivate
.