Functionality that prepare ragdoll for blending
PhysicsBlendWeight = 1.f;
const FVector RagdollLoc = GetMesh()->GetBoneLocation(HipsBoneName) + FVector(0, 0, GetCapsuleComponent()->GetScaledCapsuleHalfHeight()) + FVector(0.f, 0.f, ExecutionZOffset); //get hips bone location, this is the place where capsule is teleported
FRotator RotationBoneAxis = GetMesh()->GetBoneAxis(GetUpBoneName, EAxis::X).Rotation(); //get ragdoll orientation
RotationBoneAxis.Pitch = 0;
RotationBoneAxis.Roll = 0;
if (IsLyingOnBack()) // this checks if ragdoll is upside down and selects correct animation
{
MontageToPlay = GetUpBack;
RotationBoneAxis.Yaw += 180.f;
}
else
{
MontageToPlay = GetUpFront;
}
RotationBoneAxis = RotationBoneAxis.Clamp();
GetMesh()->KinematicBonesUpdateType = EKinematicBonesUpdateToPhysics::SkipAllBones; //this is crucial, because USkeletalMeshComponent::UpdateKinematicBonesToAnim will copy TPose bone locations to rigid bodies locations and we want to supress this logic
GetCapsuleComponent()->SetCollisionResponseToChannels(PreRagdollCapsuleCollisionResponseContainer); //restore collisions
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
SetActorLocationAndRotation(RagdollLoc, RotationBoneAxis); //set capsule location where it should be
GetMesh()->SetSimulatePhysics(false); //turn off ragdoll simulation, without it blending will be broken because ragdoll will spin and eventually will fall under the floor
SetPhysicsBlendWeight(1.f); //sets PhysicsBlendWeight on all BodyInstances below root again, because SetSimulatePhysics(false) resets them to 0.f