Projectile System (PDS) Plugin
1. Overview
The Projectile System (PDS) plugin manages the creation, simulation, and impact processing of all projectile types in your FPS game. It handles:
- Projectile Movement & Collision — Manages instantaneous hitscan traces or physically simulated projectiles via
UProjectileMovementComponent
. - Damage Calculation & Effects — Populates
FDamageContext
(from DS) and invokes the central damage pipeline. - Advanced Ballistics — Includes features for ricochet, spall generation, environmental penetration, and configurable fragmentation.
- Object Pooling (Recommended) — Designed for reuse of
ABaseProjectile
instances to minimize runtime allocation and improve performance. - Server-Authoritative Replication — Ensures all spawn, movement, and hit logic runs on the server, with clients receiving cosmetic updates.
This plugin is standalone but depends on the Damage System (DS) for core types and orchestration, and integrates upstream with the Armor System (AS) and Limb Health System (LHS).
Class Diagram
2. Core Features
- Diverse Projectile Types — Supports multiple projectile behaviors.
Hitscan
for instantaneous impacts.PhysicalBullet
with simulated mass, drag, and gravity.- Extendable for
Grenade
,Rocket
, etc., viaEProjectileType
(from DS).
- Varied Round Types — Allows definition of different ammunition characteristics.
- Supports
FMJ
,AP
,HP
,Incendiary
, etc., viaERoundType
(from DS). - Round type governs penetration capabilities, damage output, and special on-hit effects.
- Supports
- Data-Driven Archetypes — Projectile behaviors are defined in Data Assets.
UProjectileArchetypeDataAsset
defines all behavior: velocity, mass, caliber, round type, damage, and VFX/SFX.
- Advanced Ballistics Simulation — Provides options for complex projectile interactions.
- Ricochet: Configurable bounce probability and angle via
FProjectileRicochetConfig
. - Spall: Secondary fragment generation on impact, defined in
FProjectileSpallConfig
. - Penetration: Multi-surface penetration logic based on material resistance.
- Fragmentation: Allows for configurable sub-munition spawning on impact.
- Ricochet: Configurable bounce probability and angle via
- Damage & GameplayEffects Integration — Seamlessly works with the Damage System and GAS.
- On impact, PDS fills the
FDamageContext
(from DS) and callsUDamageRouterComponent::ProcessDamageEvent()
. - Uses
DirectDamageEffectClassToApply
from the projectile archetype to apply damage via Gameplay Effects.
- On impact, PDS fills the
- Object Pooling Support — Designed with performance in mind.
- Supports efficient reuse of
ABaseProjectile
actors to reduce garbage collection overhead and improve runtime performance.
- Supports efficient reuse of
3. Key C++ Classes & Data Assets
Class / Asset | Type | Responsibility |
---|---|---|
ABaseProjectile | AActor | Base class for all physical projectiles: lifecycle, movement, collision, and impact processing. |
UProjectileArchetypeDataAsset | UPrimaryDataAsset | Defines stats and behaviors: - MassKg , CaliberMm , Velocity - ERoundType , EProjectileType - BaseDamageAmount , DamageTypeClass - RicochetConfig , SpallConfig - DirectDamageGameplayEffectClass |
ProjectileSystemTypes.h | Header | PDS-specific structs: - FProjectileRicochetConfig - FProjectileSpallConfig - FProjectileImpactPayload (initial impact data for FDamageContext ) |
ItemSystemTypes.h (DS) | Header | Shared types for ammo quality: EItemInstanceQuality , FStatModifier , FQualityModifierSet . |
DamageSystemTypes.h (DS) | Header | Shared enums: ERoundType , EProjectileType , plus the FDamageContext struct. |
Module Files:
IProjectileSystemModule.h
— public interfaceProjectileSystemModule.cpp
— module startup/shutdownProjectileSystem.Build.cs
— declares dependency on"DamageSystem"
4. Directory Structure
TEXT
ProjectileSystem/ ← Plugin root
└── Source/
└── ProjectileSystem/ ← Module root
├── ProjectileSystem.Build.cs
├── Public/
│ ├── IProjectileSystemModule.h
│ ├── ProjectileSystemTypes.h ← includes DS’s DamageSystemTypes.h
│ ├── ProjectileArchetypeDataAsset.h
│ └── ABaseProjectile.h
└── Private/
├── ProjectileSystemModule.cpp
├── ProjectileArchetypeDataAsset.cpp
└── ABaseProjectile.cpp
Note:
ERoundType
,EProjectileType
,FDamageContext
, andItemSystemTypes.h
are now defined in the DamageSystem plugin.
5. Integration Points
-
Damage System (DS)
-
Dependencies:
DamageSystemTypes.h
forFDamageContext
,ERoundType
,EProjectileType
.ItemSystemTypes.h
for ammo quality.
-
Workflow:
CPP// In ABaseProjectile::ProcessImpact or hitscan handler FDamageContext Ctx; // Populate from archetype & hit: Ctx.ProjectileMassKg = Archetype->MassKg; Ctx.ProjectileCaliberMm = Archetype->CaliberMm; Ctx.ProjectileRoundType = Archetype->RoundType; Ctx.ProjectileBehaviorType = Archetype->ProjectileBehaviorType; Ctx.InitialDamagePotential = Archetype->BaseDamageAmount; Ctx.DirectDamageEffectClassToApply = Archetype->DirectDamageGameplayEffectClass; Ctx.HitLimbTag = HitLimbTag; Ctx.CurrentDamageToApply = Ctx.InitialDamagePotential; // …other fields… TargetActor->FindComponentByClass<UDamageRouterComponent>()->ProcessDamageEvent(Ctx);
-
-
Armor System (AS)
- Receives the same
FDamageContext
for mitigation inProcessDamageInteraction()
.
- Receives the same
-
Limb Health System (LHS)
- Final damage and status effects are applied to limb attributes via GAS using the populated context.
-
External Weapon System
- Selects the appropriate
UProjectileArchetypeDataAsset
and spawns or traces with the configured parameters.
- Selects the appropriate
6. Setup & Usage Notes
-
Create Archetypes
- Define
UProjectileArchetypeDataAsset
instances for each ammo/projectile type. - Use DS enums (
ERoundType
,EProjectileType
) and quality types.
- Define
-
Object Pooling
- Implement a pool for
ABaseProjectile
toSpawn
/Despawn
rather thanNew
/Destroy
.
- Implement a pool for
-
Hitscan Logic
- On server, perform line trace, then populate and dispatch
FDamageContext
as above.
- On server, perform line trace, then populate and dispatch
-
Build Dependencies
-
In
ProjectileSystem.Build.cs
, include:CSHARPPublicDependencyModuleNames.AddRange(new string[]{ "Core", "CoreUObject", "Engine", "GameplayTags", "GameplayAbilities", "DamageSystem" });
-
-
Include Paths
-
In your PDS headers:
CPP#include "DamageSystemTypes.h" // for FDamageContext, ERoundType, EProjectileType #include "ItemSystemTypes.h" // for ammo quality mappings
-
-
Define Direct Damage GE
- Ensure each archetype sets
DirectDamageGameplayEffectClass
to a validUGameplayEffect
that reads"Data.Damage"
from the context.
- Ensure each archetype sets