Skip to content

Projectiles

A projectile is an entity carrying an SProjectileComponent. SProjectileSystem sweeps it forward every frame with a continuous cast, so it never tunnels through thin walls, reports its first hit, and despawns after its lifetime.

This is far cheaper than a full rigid body and runs entirely in the ECS, so prefer it for bullets and thrown objects that only need to know what they hit.

SpawnProjectile lives on CWorld and takes the same arguments in both languages: an origin, a world-space velocity, damage, a lifetime, and optionally the entity that fired it.

entt::entity Shot = World->SpawnProjectile(Muzzle, Aim * 60.0f, 25.0f, 5.0f, Shooter);
World->GetRegistry().get<SProjectileComponent>(Shot).OnHit.AddLambda(
[](const SProjectileHitEvent& Hit)
{
LOG_INFO("hit {} at {} for {}", (uint32)Hit.HitEntity, Hit.Point, Hit.Damage);
});

The overload without an instigator defaults Damage to 0 and Lifetime to 5 seconds. Passing an instigator makes the sweep ignore that entity, so a projectile never hits whoever fired it.

You can also add SProjectileComponent to an entity yourself, in the editor under Gameplay, and set these directly.

FieldMeaning
VelocityWorld-space velocity (m/s)
GravityScaleMultiplier on world gravity; 0 = a straight line
RadiusSweep radius; 0 = a thin ray, larger for a fatter projectile
DamageCarried in the hit event; you decide how to apply it
CollisionMaskWhich collision layers it can hit, default Static + Dynamic
bDestroyOnHitDestroy the projectile on its first hit
InstigatorEntity the sweep ignores (the shooter)
OnHitFired once on hit, with an SProjectileHitEvent

SProjectileHitEvent carries Projectile, HitEntity, Point, Normal, and Damage.