(We were 4 programmers)
Ragdoll system
The ragdoll system consists a multitude of features, such as partial ragdoll for limbs, half ragdoll half animation and ragdoll while still using the capsule collider for physics.
The core of the update logic is below. Looking back, the growing number of state checks and transitions is a clear case for a proper state machine, which is how I would structure it today.
// Check if physics should be turned off
if (PhysicsOn)
{
RequiredFlyingTimeLeft -= DeltaTime;
if ((DistanceFromGround <= 2.f || VelocityLength <= 400.f) && RequiredFlyingTimeLeft <= 0.f)
{
Collider->SetSimulatePhysics(false);
PhysicsOn = false;
GetOwner()->SetActorRotation(FRotator(0.f, 0.f, 0.f));
}
}
// Have the capsule collider follow the ragdoll.
if (IsRagdolling)
{
GetOwner()->SetActorLocation(Mesh->GetComponentLocation(), false, nullptr, ETeleportType::None);
}
if (!IsRagdolling && (VelocityLength >= RagdollRequiredForce) && !JustEnteredPhysics)
{
EnterRagdoll(Velocity * RagdollTransitionMultiplier);
}
else if (!ExitingRagdoll && IsRagdolling && VelocityLength <= 40.0f && DistanceFromGround < 50.f)
{
StartEaseOut();
}
else if (ExitingRagdoll)
{
EaseOutRagdoll(DeltaTime);
}
if (JustEnteredPhysics)
{
JustEnteredPhysics = false;
}
Windblast ability
The first version used a large number of raycasts uniformly distributed in a circle, which showed up as a noticeable FPS drop in Unreal’s profiler. I replaced them with a much smaller number of sphere casts, after which the spikes were gone from the profiler.
A further improvement would be a cone intersection test plus a single ray/sphere cast per enemy to check for strength or blockage.