Page cover

Projectiles & Targeting

Jump to section...

Projectile Targeting

circle-info

Note that in order to keep the snippets within the line character limit, the code snippets below are intentionally written without worrying about const correctness.

Projectiles should fire from the character's hand towards the nearest valid target under the player's reticle. Calculating the projectile's spawn parameters takes some simple 3D math, described below.

Projectiles should fire from the character's hand to the nearest valid target under player reticle

To aim the projectile in this way, we spawn the projectile at the character's hand, facing in the direction of the target.

The SpawnLocation is easy to get, since our Character model is set up with a hand socket. We can retrieve the hand location simply by calling GetSocketLocation() on the Character mesh with the name of the hand socket.

ProjectileRotation is harder to calculate, and will take some work:

Calculating the Projectile Rotation

We need to calculate the world space rotation needed to "look at" the target (such that when the projectile moves forward, it is moving directly towards the target). Luckily, Unreal provides a convenient way to get this world space rotation, provided a vector pointing in the direction you want to look at:

FRotationMatrix::MakeFromX(FVector XAxis).Rotator()

First, this creates a rotation matrix from an X-Axis, then creates a rotator representation of this matrix. All that's left is to calculate the X-Axis that looks from the hand location, in the direction of the target. We can easily compute that by subtracting the two locations, giving us the final result:

FRotationMatrix::MakeFromX(TargetLocation - HandLocation).Rotator();

But wait! Something is still missing! We know how to generate the rotation, but still need to calculate the target location...

Calculating the Projectile Target

To find this target, we perform a line trace from the player's camera into the world where the player is looking:

We also need to configure the line trace to only collide with objects we consider attack targets:

Then we perform the trace, setting the target to the first object hit, or MaxAttackTraceDistance away if nothing was found (e.g. the player was aiming into the sky).

Full Solution

See full solution on GitHub: TAction_ProjectileAttack.cpparrow-up-right // TAction_ProjectileAttack.harrow-up-right

Projectile Classes

circle-info

Functionality for projectiles are implemented in C++. Unreal's Blueprints / UI is only used to assign assets and fine-tune gameplay parameters (damage values, delays, etc.).

Projectile Base Class

A projectile base class TProjectileBase handles the basic setup of a projectile.

  • Can collide with the environment, exploding upon impact

  • Provides the following virtual functions:

    • OnActorHit() - callback when projectile hits the environment (blocking collision)

    • Explode() - play cosmetic effects and destroy self. Triggered by OnActorHit() by default

  • Contains the basic components shared by all projectiles:

    • USphereComponent - Sphere primitive used for collision detection

    • UProjectileMovementComponent - Handle velocity, acceleration, curvature, etc.

    • UParticleSystemComponent - Projectile and explosion VFX

    • UAudioComponent - Projectile and explosion sounds

See it on GitHub: TProjectileBase.cpparrow-up-right // TProjectileBase.harrow-up-right

Magic Projectile

This magic projectile deals an initial burst of damage, then applies the 'burning' effect to actors it hits.

Magic projectiles are the most basic attack a player can perform, dealing damage, applying debuffs, and more. They extend the projectile base class with the following functionality:

Gameplay:

  • Deals damage upon overlap (if overlapped object implements health)

  • Can apply buffs/debuffs on overlap (if overlapped object implements actions)

  • Can be parried / reflected (if overlapped object has parry tag)

Cosmetic:

  • Applies camera shake around impact point

See it on GitHub: TProjectile_Magic.cpparrow-up-right // TProjectile_Magic.harrow-up-right

Dash Projectile

Left: Player uses dash ability three times. Right: Shows it from the perspective of another player (via networked multiplayer).

Dash projectiles fly forward, exploding on impact or after a set duration expires, whichever comes first. Upon exploding, there is a short delay before the player is teleported to the explosion's impact point. They extend the projectile base class with the following functionality:

Gameplay:

  • Explodes on impact or after a set duration, teleporting player to impact location after a short delay

  • Configurable delay between spawn and explosion, and explosion and teleport

See it on GitHub: TProjectile_Dash.cpparrow-up-right // TProjectile_Dash.harrow-up-right

Last updated