Ragdoll Physics on Death

This is the code im using to change the character into a ragdoll, which can also be found in some tutorials/examples



bool ASwatCharacter::Die(float Damage, FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
{
    if (!bIsDying)
    {
        bReplicateMovement = false;
        bTearOff = true;

        DetachFromControllerPendingDestroy();

        /* Disable all collision on capsule */
        UCapsuleComponent* CapsuleComp = GetCapsuleComponent();
        CapsuleComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
        CapsuleComp->SetCollisionResponseToAllChannels(ECR_Ignore);

        GetMesh()->SetCollisionProfileName(TEXT("Ragdoll"));
        SetActorEnableCollision(true);

        if (!bIsRagdoll)
        {
            // Ragdoll
            GetMesh()->SetAllBodiesSimulatePhysics(true);
            GetMesh()->SetSimulatePhysics(true);
            GetMesh()->WakeAllRigidBodies();
            GetMesh()->bBlendPhysics = true;

            UCharacterMovementComponent* CharacterComp = Cast<UCharacterMovementComponent>(GetMovementComponent());
            if (CharacterComp)
            {
                CharacterComp->StopMovementImmediately();
                CharacterComp->DisableMovement();
                CharacterComp->SetComponentTickEnabled(false);
            }

            SetLifeSpan(10.0f);
            bIsRagdoll = true;
        }
    }

    /* Apply physics impulse on the bone of the enemy skeleton mesh we hit (ray-trace damage only) */
    if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
    {
        FPointDamageEvent PointDmg = *((FPointDamageEvent*)(&DamageEvent));
        {
            GetMesh()->AddImpulseAtLocation(PointDmg.ShotDirection * 5000, PointDmg.HitInfo.ImpactPoint, PointDmg.HitInfo.BoneName);
        }
    }
    if (DamageEvent.IsOfType(FRadialDamageEvent::ClassID))
    {
        FRadialDamageEvent RadialDmg = *((FRadialDamageEvent const*)(&DamageEvent));
        {
            GetMesh()->AddRadialImpulse(RadialDmg.Origin, RadialDmg.Params.GetMaxRadius(), 100000, ERadialImpulseFalloff::RIF_Linear);
        }
    }

    return true;
}


1 Like