In this post, I’ll demonstrate how I implemented weapon-based raycasting (line tracing from weapon) as an alternative to the default center-screen approach.
This is in the context of my Single-player third-person shooter game which is based on a Lyra Starter Game in Unreal Engine 5.4.
Here is the in-game demonstration of the solution (from 1:04, 13 seconds). Red dynamic crosshair points to the actual hit location:

Handled Challenges
Ranged weapon vs screen raycasting hit locations (e.g. shooting through a wall corner)
Challenge:
- Ranged weapon raycasting hit location does not always match the target that a player sees at the crosshair on their screen.
In other words, if there is something on the line of fire (which originates from the weapon), the player should be aware of what will be hit when firing. And this hit location can be not what is at the crosshair at the screen center.
My approach to the challenge:
- Display an auxiliary dynamic crosshair at the expected hit location.
Weapon penetrating an obstacle (e.g. a character is very close to a wall shooting through the wall)
Challenge:
- If a character comes too close to an obstacle (e.g. a wall) normal shooting is disrupted.
My approach to the challenge:
- When a weapon penetrates a hittable object, move the trace line start inside the character (see UMBCG_LyraGA_RangedWeapon::GetLocationBeforePossibleObstacleOnWeaponLine function).
My Solution
- All heavy-lifting (raycasting logic) is implemented in C++ (in a custom copy of ULyraGameplayAbility_RangedWeapon). See UMBCG_LyraGA_RangedWeapon in my solution.
- Gameplay Ability blueprint (based on UMBCG_LyraGA_RangedWeapon, and added to all weapon ability sets e.g. to AbilitySet_ShooterPistol) broadcasts a message (using Gameplay Message Subsystem) with some time interval informing whether there is an obstacle on the line of fire. See GA_Weapon_Fire_ObstacleCheck_MBCG in my solution.
- Visualization (the dynamic crosshair) is done in ULyraTaggedWidget widget in blueprints, which is added to the player’s HUD layout (W_ShooterHUDLayout). The ULyraTaggedWidget listens to the mentioned message and displays the dynamic crosshair in the required screen position. See W_ObstacleCrosshairs_MBCG in my solution.
C++ code
Here is the repo with my custom copy of ULyraGameplayAbility_RangedWeapon class. Please note that due to restrictive Epic Games’ EULA terms, I can’t publish code that belongs to Epic. Therefore, I removed the code that belongs to Epic from the published class.
Just a reminder about the entry point. The ranged weapon functionality in Lyra is handled in ULyraGameplayAbility_RangedWeapon class.
GA_Weapon_Fire blueprint calls
ULyraGameplayAbility_RangedWeapon::StartRangedWeaponTargeting
And this function calls
PerformLocalTargeting(/*out*/ FoundHits);
I modified PerformLocalTargeting() function and added other functions.
I marked the added code with the following comments:
// @MBCG - START OF CODE
// @MBCG - END OF CODE
Gameplay Ability blueprint

Visualization of the dynamic crosshair with a widget
